簡體   English   中英

我怎么知道一個字符串中有多少匹配被替換?

[英]How can I know how many matches get replaced in a string?

假設我有一個如下所示的函數:

function countReplacements ( string, search, replacement ) {
    string.replace ( search, replacement );
}

知道有多少匹配被替換到字符串中的最干凈、最可靠的方法是什么?

我想到了以下可能的解決方案:

  • 使用代理包裝replacement值,每次訪問其代理值時都會記錄日志。 但是,這不能轉換為舊版本的 JS。

  • 重新實現String.prototype.replace使用的算法,以便每次替換某些內容時都會記錄下來。 這根本不是很干凈。

  • 如果search是字符串或非全局正則表達式,我可以檢查string包含/匹配它。 但是,如果search是全局正則表達式,那么當 JS 將支持后視時,我不確定這是否可行,也許所有匹配項都是在實際替換它們之前計算出來的? 如果不是這種情況,任何替換都可能導致以下后視不再匹配,或者現在匹配它在原始字符串中不匹配的內容。

您認為解決問題的最佳方法是什么?

對於替換為字符串的普通情況,對於.replace的第二個參數,使用回調函數而不是普通replacement字符串,並讓回調增加一個變量:

 function countReplacements(string, search, replacement) { let count = 0; const result = string.replace(search, () => { count++; return replacement; }); return { count, result }; } console.log(countReplacements('foobar', /o/g, 'a'));

對於更復雜的情況,當replacement是一個函數或包含組引用的字符串時,您要么必須自己重新實現String.prototype.replace :使用提供給.replace的參數來獲取完整匹配和組:

 function countReplacements(string, search, replacement) { let count = 0; const result = string.replace(search, (match, ...groups) => { count++; return replacement .replace(/\\$(\\d+|&)/g, (_, indicator) => { if (indicator === '&') return match; if (/^\\d+$/.test(indicator)) return groups[indicator - 1]; // and so on for other `$`s }); }); return { count, result }; } console.log(countReplacements ( 'foobar', /(o)/g, '$1_' ));

一個更懶惰但更容易實現的版本只是調用match並檢查結果的length ,盡管這需要使用正則表達式遍歷字符串兩次

 function countReplacements(string, search, replacement) { const match = string.match(search); const count = match ? match.length : 0; const result = string.replace(search, replacement); return { count, result }; } console.log(countReplacements ( 'foobar', /(o)/g, '$1_' ));

如果搜索是字符串或非全局正則表達式,我可以檢查字符串是否包含/匹配它。 但是,如果搜索是全局正則表達式,那么當 JS 將支持后視時,我不確定這是否可行,也許所有匹配項都是在實際替換它們之前計算出來的? 如果不是這種情況,任何替換都可能導致以下后視不再匹配,或者現在匹配它在原始字符串中不匹配的內容。

這不會成為問題 - 除了.replace之外,使用.match獲取計數的唯一問題是它需要遍歷字符串兩次。 字符串的替換都是一次計算的,其中環視正在查看原始字符串 然后,一旦找到所有匹配項並計算替換項,每個匹配的子串都將被替換為它的替換項。

暫無
暫無

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

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