Есть ли лучший способ извлечь информацию из строки?
Допустим, у меня есть массив строк, и мне нужна конкретная информация о них, что будет простым способом сделать это?
Предположим, что массив был
let infoArr = [
"1 Ben Howard 12/16/1988 apple",
"2 James Smith 1/10/1999 orange",
"3 Andy Bloss 10/25/1956 apple",
"4 Carrie Walters 8/20/1975 peach",
"5 Doug Jones 11/10/1975 peach"
];
Допустим, я хотел, чтобы дата была извлечена и сохранена в другом массиве, ну, я мог бы сделать такую функцию
function extractDates(arr){
let dateRegex = /(\d{1,2}\/){2}\d{4}/g, dates = "";
let dateArr = [];
for(let i = 0; i<arr.length; i++){
dates = /(\d{1,2}\/){2}\d{4}/g.exec(arr[i])
dates.pop();
dateArr.push(dates);
}
return dateArr.flat();
}
Хотя это работает, это неуклюже и требует, чтобы я pop(), потому что это возвратит массив массивов, то есть: ["16.12.1988", "16/"], плюс мне нужно впоследствии вызвать flat.
Другим вариантом будет подстрока строк с заданной позицией, где мне нужно знать шаблон регулярных выражений.
function extractDates2(arr){
let dates = [];
for(let i = 0; i<arr.length; i++){
let begin = regexIndexOf(arr[i], /(\d{1,2}\/){2}\d{4}/g);
let end = regexIndexOf(arr[i], /[0-9] /g, begin) + 1;
dates.push(arr[i].substring(begin, end));
}
return dates;
}
И, конечно, есть функция regexIndexOf
function regexIndexOf(str, regex, start = 0){
let indexOf = str.substring(start).search(regex);
indexOf = (indexOf >= 0) ? (indexOf + start) : -1;
return indexOf;
}
Опять же, эта функция также работает, но кажется, что нужно извлечь что-то простое. Есть ли более простой способ извлечь данные в массив?
Ответы
Ответ 1
Одним из вариантов было бы объединить строки сепаратором, который не будет соответствовать, как ,
, то просто выполнить глобальный матч, чтобы получить массив дат из него:
let infoArr = [
"1 Ben Howard 12/16/1988 apple",
"2 James Smith 1/10/1999 orange",
"3 Andy Bloss 10/25/1956 apple",
"4 Carrie Walters 8/20/1975 peach",
"5 Doug Jones 11/10/1975 peach"
];
const result = infoArr
.join(',')
.match(/(\d{1,2}\/){2}\d{4}/g);
console.log(result);
Ответ 2
Одним из подходов может быть использование map() над элементами массива с применением соответствия для каждого элемента и, наконец, вызовом flat() для получения желаемого результата:
let infoArr = [
"1 Ben Howard 12/16/1988 apple",
"2 James Smith 1/10/1999 orange",
"3 Andy Bloss 10/25/1956 apple",
"4 Carrie Walters 8/20/1975 peach",
"5 Doug Jones 11/10/1975 peach"
];
const result = infoArr.map(o => o.match(/(\d{1,2}\/){2}\d{4}/g)).flat();
console.log(result);
Ответ 3
Хотя это работает, это неуклюже и требует pop()
потому что он будет возвращать массив массивов, то есть: ["12/16/1988", "16/"]
, плюс мне нужно впоследствии вызывать flat
.
Метод regex exec
всегда имеет свое совпадение в свойстве 0
(при условии, что оно совпадает вообще), вы можете просто получить к нему доступ и передать его в свой массив:
let infoArr = [
"1 Ben Howard 12/16/1988 apple",
"2 James Smith 1/10/1999 orange",
"3 Andy Bloss 10/25/1956 apple",
"4 Carrie Walters 8/20/1975 peach",
"5 Doug Jones 11/10/1975 peach"
];
function extractDates(arr){
const dateRegex = /(\d{1,2}\/){2}\d{4}/g;
const dateArr = [];
for (const str of arr){
const date = /(\d{1,2}\/){2}\d{4}/g.exec(str);
dateArr.push(date[0]);
}
return dateArr;
}
console.log(extractDates(infoArr));
Ответ 4
Вы можете использовать reduce()
вместо циклов для сопряжения кода. Просто будьте осторожны, чтобы сохранить null
в массиве, если нет совпадений.
let infoArr = [
"1 Ben Howard 12/16/1988 apple",
"2 James Smith 1/10/1999 orange",
"3 Andy Bloss 10/25/1956 apple",
"4 Carrie Walters 8/20/1975 peach",
"5 Doug Jones 11/10/1975 peach"
];
let regex = /(\d{1,2}\/){2}\d{4}/g
let dates = infoArr.reduce((arr, s) => arr.concat(s.match(regex) || []) , [])
console.log(dates)