使用正则表达式替换第n个匹配项

3

我正在尝试找到一种方法来替换类似这样的更多匹配项的第n个匹配项。

string = "one two three one one"

如何定位“one”的第二个出现位置?

是否可以像这样做?

string.replace(/\bone\b/gi{2}, "(one)")

获得这样的东西

"one two three (one) one"

我已经做了一个jsfiddle,它可以工作,但感觉不太对。代码很多,对于一个简单的事情来说很令人困惑。 https://jsfiddle.net/Rickii/7u7pLqfd/
2个回答

2
更通用的方法是使用替换函数。

// Replace the n-th occurrence of "re" in "input" using "transform"
function replaceNth(input, re, n, transform) {
  let count = 0;

  return input.replace(
    re, 
    match => n(++count) ? transform(match) : match);
}

console.log(replaceNth(
  "one two three one one", 
  /\bone\b/gi,
  count => count ===2,
  str => `(${str})`
));

// Capitalize even-numbered words.
console.log(replaceNth(
  "Now is the time",
  /\w+/g,
  count => !(count % 2),
  str => str.toUpperCase()));


谢谢你的建议。这是一个很好的替代方案,比Rizwan M.Tumans的解决方案更适合我。我会调查一下哪种方法最适合我。 - Rickard Dahlström

2

更新:

为了使其动态化,请使用以下代码:

((?:.*?one.*?){1}.*?)one

其中值1表示(n-1),在您的情况下n=2

并替换为:

$1\(one\)

Regex101 Demo

const regex = /((?:.*?one.*?){1}.*?)one/m;
const str = `one two three one one asdfasdf one asdfasdf sdf one`;
const subst = `$1\(one\)`;
const result = str.replace(regex, subst);
console.log( result);


嘿,这个也可以工作:((?:.*?one.*?){1})one。我只是从你的解决方案中删除了 {1} 后面的 .*?,请问这样做是否正确? - Aashit Garodia

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接