簡體   English   中英

有沒有更好的方法從字符串中提取信息?

[英]Is there a better way to extract information from a string?

假設我有一個字符串數組,我需要來自它們的具體信息,這將是一種簡單的方法嗎?

假設數組是這樣的:

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()因為它會返回一個數組數組,即: ["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;
 }    

當然它使用下一個regexIndexOf()函數:

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

同樣,這個函數也可以工作,但是完成簡單的提取似乎太糟糕了。 有沒有更簡單的方法將數據提取到數組?

一種方法是使用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); 

或者,您可以使用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); 

此外,如果您需要從最終數組中刪除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);

數據沖突的示例:

 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); 

沒有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)); 

一種選擇是參加由該會不匹配,就像一個分隔字符串, ,那么就執行全局匹配,以從中獲取日期的數組:

 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); 

雖然這很有效,但它很笨重並需要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)); 

(當然你也可以在map回調中做同樣的事情)

您可以使用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) 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM