首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >只替换全局正则表达式的第一个匹配项。

问只替换全局正则表达式的第一个匹配项。
EN

Stack Overflow用户
提问于 2017-07-26 21:15:43
回答 1查看 1.1K关注 0票数 7

我正在编写一个函数来递归地替换字符串中正则表达式的匹配。替换可以是一个函数,就像使用vanilla .replace一样,该函数可以通过其参数之一访问原始字符串。

我希望我的函数在每次迭代中只替换一个匹配项。对于非全局正则表达式,情况总是如此。但是,该函数接收的一些正则表达式将是全局的。执行传统的.replace(regex, replacement)意味着它可以在每次迭代中多次替换,这不仅会扰乱匹配的处理顺序,而且还会将不正确的索引和原始字符串传递给替换函数。

例如:

代码语言:javascript
复制
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];
  })
);

这输出

代码语言:javascript
复制
abcdef
abcdef
abcdef
ace
ae
a

当所需的输出是

代码语言:javascript
复制
abcdef
acdef
adef
aef
af
a

如何使函数在每次迭代中只处理一次匹配,无论regex是否有g标志?请注意,我使用该函数的方式是,第二个参数始终是正则表达式(我对此没有控制权,也不知道regex是否带有g标志)。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-07-26 21:44:35

这样做的最佳方法似乎是手动从regex中删除g标志。下面是我能找到的最跨平台的方法,使用regex.toString()获取正则表达式的字符串表示:

代码语言:javascript
复制
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,这就容易多了:

代码语言:javascript
复制
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;
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45337572

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档