gpt4 book ai didi

javascript - 我怎么知道字符串中有多少匹配项被替换了?

转载 作者:行者123 更新时间:2023-11-29 23:15:50 26 4
gpt4 key购买 nike

假设我有一个如下所示的函数:

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 是一个函数或一个包含组引用的字符串时,您要么必须在您的自己:使用提供给 .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_' ));

If search is a string or a non-global regex I can check if string includes/matches it. But if search is a global regex, when JS will have support for lookbehinds I'm not sure this will work, maybe all matches are computed before actually replacing them? If this isn't the case any replacement may cause the following lookbehinds to no longer match, or to now match things that it wouldn't have matched in the original string.

这不是问题 - 除了 .replace 之外,使用 .match 获取计数的唯一问题是它需要遍历字符串两次.字符串的替换都是一次性计算的,环视是查看原始字符串。然后,一旦找到所有匹配项并计算出替换项,每个匹配的子字符串将被替换为它的替换项。

关于javascript - 我怎么知道字符串中有多少匹配项被替换了?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52826265/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com