有没有更好的方法从字符串中提取信息?

Tra*_*vis 18 javascript regex arrays

假设我有一个字符串数组,我需要来自它们的具体信息,这将是一种简单的方法吗?

假设数组是这样的:

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"
];
Run Code Online (Sandbox Code Playgroud)

假设我想提取日期并将其保存到另一个数组中,我可以创建这样的函数

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();
}
Run Code Online (Sandbox Code Playgroud)

虽然这很有效,但它很笨重并且需要,pop()因为它将返回一个数组数组,即:["12/16/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;
 }    
Run Code Online (Sandbox Code Playgroud)

当然它使用下一个regexIndexOf()功能:

function regexIndexOf(str, regex, start = 0)
{
  let indexOf = str.substring(start).search(regex);
  indexOf = (indexOf >= 0) ? (indexOf + start) : -1;
  return indexOf;
}
Run Code Online (Sandbox Code Playgroud)

同样,这个函数也可以工作,但是完成简单的提取似乎太糟糕了.有没有更简单的方法将数据提取到数组?

Shi*_*rsz 21

一种方法是使用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);
Run Code Online (Sandbox Code Playgroud)

或者,您可以使用flatMap():

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.flatMap(o => o.match(/(\d{1,2}\/){2}\d{4}/g));

console.log(result);
Run Code Online (Sandbox Code Playgroud)

此外,如果您需要null从最终数组中删除值,如果没有日期的字符串,您可以应用filter(),如下所示:

const result = infoArr.map(o => o.match(/(\d{1,2}\/){2}\d{4}/g))
                      .flat()
                      .filter(date => date !== null);

const result = infoArr.flatMap(o => o.match(/(\d{1,2}\/){2}\d{4}/g))
                      .filter(date => date !== null);
Run Code Online (Sandbox Code Playgroud)

数据冲突的示例:

let infoArr = [
  "1 Ben Howard 12/16/1988 apple 10/22/1922",
  "2 James Smith orange",
  "3 Andy Bloss 10/25/1956 apple",
  "4 Carrie Walters 8/20/19075 peach",
  "5 Doug Jones 11/10-1975 peach"
];

const result = infoArr.flatMap(o => o.match(/(\d{1,2}\/){2}\d{4}/g))
                      .filter(date => date !== null); /* or filter(date => date) */

console.log(result);
Run Code Online (Sandbox Code Playgroud)

没有flat()的替代方案:

由于flat()并且flatMap()目前仍处于"实验性"状态,可能会发生变化,并且某些浏览器(或某些版本)不支持它,您可以使用下一个替代方案,其限制只会在每个方面获得第一个匹配string:

const infoArr = [
  "1 Ben Howard 12/16/1988 apple 10/22/1922",
  "2 James Smith orange",
  "3 Andy Bloss 10/25/1956 apple",
  "4 Carrie Walters 8/20/19075 peach",
  "5 Doug Jones 11/10-1975 peach"
];

const getData = (input, regexp, filterNulls) =>
{
    let res = input.map(o =>
    {
        let matchs = o.match(regexp);
        return matchs && matchs[0];
    });

    return filterNulls ? res.filter(Boolean) : res;
}

console.log(getData(infoArr, /(\d{1,2}\/){2}\d{4}/g, false));
console.log(getData(infoArr, /(\d{1,2}\/){2}\d{4}/g, true));
Run Code Online (Sandbox Code Playgroud)

  • 如果任何行不包含日期,您将在数组中以"null"值结束. (2认同)
  • 另外,请记住,"flat"和"flatMap"目前仍处于"实验性"状态,可能会发生变化. (2认同)

Cer*_*nce 19

一种选择是通过一个不匹配的分隔符连接字符串,,然后只需执行全局匹配即可从中获取日期数组:

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);
Run Code Online (Sandbox Code Playgroud)

  • 这个解决方案似乎是最快的:http://jsben.ch/w9geK另外它的优点是它处理没有日期的数组元素(不会在数组中创建空值),请记住,如果你是试图通过基于原始数组的索引来获取特定元素的日期,如果某些元素没有日期,它可能不会排列 (4认同)