我正在编写一个函数来递归地替换字符串中正则表达式的匹配。替换可以是一个函数,就像使用vanilla .replace一样,该函数可以通过其参数之一访问原始字符串。
我希望我的函数在每次迭代中只替换一个匹配项。对于非全局正则表达式,情况总是如此。但是,该函数接收的一些正则表达式将是全局的。执行传统的.replace(regex, replacement)意味着它可以在每次迭代中多次替换,这不仅会扰乱匹配的处理顺序,而且还会将不正确的索引和原始字符串传递给替换函数。
例如:
function recursiveReplace(string, regex, replacement) {
for (var i = 1e8; i > 0 && regex.test(string); i--)
string = string.replace(regex, replacement);
return string;
}
console.log(
recursiveReplace("abcdef", /../g, function (match, index, original) {
console.log(original);
return match[0];
})
);这输出
abcdef
abcdef
abcdef
ace
ae
a当所需的输出是
abcdef
acdef
adef
aef
af
a如何使函数在每次迭代中只处理一次匹配,无论regex是否有g标志?请注意,我使用该函数的方式是,第二个参数始终是正则表达式(我对此没有控制权,也不知道regex是否带有g标志)。
发布于 2017-07-26 21:44:35
这样做的最佳方法似乎是手动从regex中删除g标志。下面是我能找到的最跨平台的方法,使用regex.toString()获取正则表达式的字符串表示:
function recursiveReplace(string, regex, replacement) {
regex = eval(regex.toString().replace(/[a-z]*$/, function (s) {
return s.replace('g', '');
}));
for (var i = 1e8; i > 0 && regex.test(string); i--)
string = string.replace(regex, replacement);
return string;
}有了ES6特性、RegExp(regex)和RegExp#flags,这就容易多了:
function recursiveReplace(string, regex, replacement) {
regex = RegExp(regex, regex.flags.replace('g', ''));
for (var i = 1e8; i > 0 && regex.test(string); i--)
string = string.replace(regex, replacement);
return string;
}https://stackoverflow.com/questions/45337572
复制相似问题