簡體   English   中英

如何使用 Javascript 在給定字符串中第 n 次出現一組子字符串?

[英]How to get the nth occurrence of a set of substrings in a given string using Javascript?

我有一個純字符串

"A <br> B <br/> C <br /> D <br/>" 

和一組可能的子串,比如

['<br>','<br/>','<br />'];

在字符串中找到特定字符串第 n 次出現的整個字符串中的索引很簡單,所以我可以在第 n 個“ <br> ”或第 n 個“ <br/> ”的整個字符串中找到索引,但是如何找到這些字符串中的任何一個的第 n 次出現?

例如,如果我需要 2' 出現,在這種情況下將是 9' 字符,即第一個<br>計為第一次出現,第二個<br/>計為第二次出現

編輯:查找特定字符串的第 n 次出現的索引可以這樣完成

var index = string.split('<br>', 2).join('<br>').length;

所以我可以找到單獨的事件。 問題是找到這些字符串中的任何一個的出現。

您可以嘗試像這樣使用正則表達式:

 let testString="A <br> B <br/> C <br /> D <br/>"; //Array of substrings to be searched for let testItems=['<br>','<br/>','<br />']; //Construction of the regular expression from the given array let regex=new RegExp(testItems.join("|"),"g"); //Getting all matches for the provided regex and reducing it to an array of indices only let indices=[...testString.matchAll(regex)].map(match=>match.index); console.log(indices);

第 n 次出現可以很容易地從索引數組中恢復。 如果您需要知道哪個 ZE83AED3DDF4667DEC0DAAAACB2BB3BE0BZ 也被擊中,您也可以修改它。

更新

上面的答案沒有考慮到搜索項包含正則表達式特殊字符的可能性。 要處理這種情況,必須手動轉義輸入,如下所示。

 let testString="A <br> B <br/> C <br /> D <br/> E <br $> F <br []/>"; //Array of substrings to be searched for let testItems=['<br>','<br/>','<br />','<br $>','<br []/>']; //Function to return an escaped version of the input string let escapeRegex=(string)=> string.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'); //Construction of the regular expression from the given array let regex=new RegExp(testItems.map(item=>escapeRegex(item)).join("|"),"g"); //Getting all matches for the provided regex and reducing it to an array of indices only let indices=[...testString.matchAll(regex)].map(match=>match.index); console.log(indices);

The function for escaping the input was borrowed from an answer to the question Is there a RegExp.escape function in JavaScript?

感謝@ScottSauyet 和@Ivar 的反饋

只要您不希望尋找第 10,000 個匹配項或類似的匹配項,遞歸解決方案在這里是有意義的。 這是一種方法:

 const indexOfAny = (string, substrings, pos = 0) => { const positions = substrings.map (ss => string.indexOf (ss, pos)).filter (n => n > -1) return positions.length == 0? -1: Math.min (... positions) } const nthOfAny = (n, string, subtrings, pos = 0) => { const first = indexOfAny (string, substrings, pos) return n <= 1? first: first == -1? -1: nthOfAny (n - 1, string, substrings, 1 + indexOfAny (string, substrings, pos)) } const string = 'A <br> B <br/> C <br /> D <br/>' const substrings = ['<br>','<br/>','<br />'] console. log ( nthOfAny (2, string, substrings) ) console.log ( [1, 2, 3, 4, 5, 6].map (n => nthOfAny (n, string, substrings)) )

我們首先定義indexOfAny ,它接受一個字符串、一個要搜索的子字符串數組和(可選)一個初始 position,它返回找到的第一個的 position,如果沒有找到,則返回-1

然后nthOfAny采用一個序數( 1代表第一個, 2代表第二個等)和與上面相同的 arguments 並通過將pos增加到先前找到的一個並減小n直到它遇到只返回結果的基本情況來遞歸地找到一個的indexOfAny

有相當多的額外復雜性意味着使用-1表示沒有找到任何東西,以匹配indexOf 對於這種情況,一個更簡單的解決方案將返回Infinity

const indexOfAny = (string, substrings, pos = 0) => 
  Math.min (
    ... substrings .map (ss => string .indexOf (ss, pos)) .filter (n => n > -1)
  )

const nthOfAny = (n, string, subtrings, pos = 0) => 
  n <= 1
    ? indexOfAny (string, substrings, pos)
    : nthOfAny (n - 1, string, substrings, 1 + indexOfAny (string, substrings, pos))

暫無
暫無

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

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