我在字符串前后都有 HTML 代码:
name="some_text_0_some_text"
我想用以下内容替换0:!NEW_ID!
所以我做了一个简单的正则表达式:
.*name="\w+(\d+)\w+".*
但我不知道如何专门替换捕获的块。
有没有办法用其他一些字符串替换像 ($1) 这样的捕获结果?
结果是:
name="some_text_!NEW_ID!_some_text"
我在字符串前后都有 HTML 代码:
name="some_text_0_some_text"
我想用以下内容替换0:!NEW_ID!
所以我做了一个简单的正则表达式:
.*name="\w+(\d+)\w+".*
但我不知道如何专门替换捕获的块。
有没有办法用其他一些字符串替换像 ($1) 这样的捕获结果?
结果是:
name="some_text_!NEW_ID!_some_text"
一种解决方案是为前面和后面的文本添加捕获:
str.replace(/(.*name="\w+)(\d+)(\w+".*)/, "$1!NEW_ID!$3")
现在 Javascript 具有后视功能(从ES2018 开始),在较新的环境中,您可以完全避免在此类情况下使用组。相反,回顾后为你捕捉组,先行用于之后的部分,并将其替换之前会发生什么只是 !NEW_ID!:
const str = 'name="some_text_0_some_text"';
console.log(
str.replace(/(?<=name="\w+)\d+(?=\w+")/, '!NEW_ID!')
);
使用这种方法,完全匹配的只是需要更换的部分。
(?<=name="\w+)- Lookbehind for name=",后跟单词字符(幸运的是,在 Javascript 中,lookbehinds 不必固定宽度!)\d+ - 匹配一个或多个数字 - 模式的唯一部分不在环视中,字符串的唯一部分将出现在结果匹配中(?=\w+")- 前瞻单词字符后跟"
`请记住,lookbehind 很新。它适用于现代版本的 V8(包括 Chrome、Opera 和 Node),但不适用于大多数其他环境,至少目前还没有。因此,虽然您可以在 Node 和您自己的浏览器中可靠地使用 Lookbehind(如果它在现代版本的 V8 上运行),但它还没有得到随机客户端的充分支持(例如在公共网站上)。
对马修答案的一点改进可能是前瞻而不是最后一个捕获组:
.replace(/(\w+)(\d+)(?=\w+)/, "$1!NEW_ID!");
或者你可以在小数点上拆分并像这样加入你的新 ID:
.split(/\d+/).join("!NEW_ID!");
示例/基准在这里:https : //codepen.io/jogai/full/oyNXBX
使用两个捕获组也是可能的;我还会在数字之前和之后包含两个破折号,作为额外的左右边界,修改后的表达式看起来像:
(.*name=".+_)\d+(_[^"]+".*)
const regex = /(.*name=".+_)\d+(_[^"]+".*)/g;
const str = `some_data_before name="some_text_0_some_text" and then some_data after`;
const subst = `$1!NEW_ID!$2`;
const result = str.replace(regex, subst);
console.log(result);
如果你想探索/简化/修改表达式,它已在regex101.com 的右上角面板中进行了 解释。如果您愿意,您还可以在此链接中观看它如何与某些示例输入匹配。
jex.im可视化正则表达式:
一个更简单的选择是只捕获数字并替换它们。
const name = 'preceding_text_0_following_text';
const matcher = /(\d+)/;
// Replace with whatever you would like
const newName = name.replace(matcher, 'NEW_STUFF');
console.log("Full replace", newName);
// Perform work on the match and replace using a function
// In this case increment it using an arrow function
const incrementedName = name.replace(matcher, (match) => ++match);
console.log("Increment", incrementedName);