我在字符串前后有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"
Answers:
一种解决方案是为前面和后面的文本添加捕获:
str.replace(/(.*name="\w+)(\d+)(\w+".*)/, "$1!NEW_ID!$3")
$
为该(\w+)
组分配基数为1的索引,可以用a替换该索引,因此第一个单词在组中,并且变为$1
,中间部分(\d+)
是第二组,(但在替换中忽略),而第三组是$3
。因此,当您提供替换字符串时"$1!new_ID!$3"
,$ 1和$ 3会自动被第一组和第三组替换,从而允许第二组被新字符串替换,并保持其周围的文本。
现在(从ES2018开始)Javascript已经落后了,在较新的环境中,您可以完全避免在此类情况下进行分组。相反,回顾后为你捕捉组之前会发生什么,以及超前的来后,并将其替换只是 !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"
,后跟单词字符(幸运的是,lookbehinds在Javascript中不必固定宽度!)\d+
-匹配一个或多个数字-模式的唯一部分不在环视范围内,字符串的唯一部分将出现在结果匹配项中(?=\w+")
-前瞻单词字符,后跟"
`请记住,向后看是很新的。它可以在V8的现代版本(包括Chrome,Opera和Node)中运行,但在大多数其他环境中(至少目前还不能)使用。因此,尽管您可以在Node和自己的浏览器中可靠地使用lookbehind(如果它在V8的现代版本上运行),但随机客户端(例如在公共网站上)尚不能提供足够的支持。
\d+
,对吗?
match => match * 2
。这些数字仍然是完整的比赛,因此无需分组
对Matthew答案的一点改进可以是先行,而不是最后一个捕获组:
.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);