ChatGPT解决这个技术问题 Extra ChatGPT

如何仅替换捕获的组?

我在字符串之前和之后都有 HTML 代码:

name="some_text_0_some_text"

我想将 0 替换为:!NEW_ID!

所以我做了一个简单的正则表达式:

.*name="\w+(\d+)\w+".*

但我看不到如何专门替换捕获的块。

有没有办法用其他字符串替换像 ($1) 这样的捕获结果?

结果将是:

name="some_text_!NEW_ID!_some_text"

A
Adam

一种解决方案是为前面和后面的文本添加捕获:

str.replace(/(.*name="\w+)(\d+)(\w+".*)/, "$1!NEW_ID!$3")

来自未来的问候!您的解决方案看起来非常整洁。你能解释一下你的答案吗?
括号用于创建“组”,然后分配一个基数为 1 的索引,可以用 $ 替换,因此第一个单词 (\w+) 在一个组中,变成 $1,中间部分 (\d+) 是第二组,(但在替换中被忽略),第三组是 $3。因此,当您给出 "$1!new_ID!$3" 的替换字符串时,$1 和 $3 会自动替换为第一组和第三组,允许第二组替换为新字符串,并保持其周围的文本。
话虽如此,虽然我了解它是如何工作的,但我希望有一个更优雅的解决方案 >.< 不过,我现在可以继续编写我的代码了!
1) 你甚至不需要捕获 \d+ 2) 你为什么说它不优雅?捕获是为了保留东西,而不是扔掉它。你想要保留的是 AROUND \d+,所以捕捉这些周围的部分真的很有意义(并且足够优雅)。
很好的解决方案。如果我们想使用捕获组作为转换的基础来替换捕获组怎么办?有没有同样优雅的解决方案来做到这一点?目前我将捕获的组存储在一个列表中,循环它们,并在每次迭代时用转换后的值替换捕获组
A
Aaron Dunigan AtLee

既然 Javascript 具有后向功能(自 ES2018 起),在较新的环境中,您可以在此类情况下完全避免使用组。相反,向后查看您正在捕获的组之前的内容,并向前查看之后的内容,并替换为 just !NEW_ID!

常量 str = 'name="some_text_0_some_text"'; console.log(str.replace(/(?<=name="\w+)\d+(?=\w+")/, '!NEW_ID!'));

使用这种方法,完全匹配的只是需要替换的部分。

(?<=name="\w+) - name="的后视,后跟单词字符(幸运的是,在 Javascript 中后视不必是固定宽度!)

\d+ - 匹配一个或多个数字 - 模式的唯一部分不在环视中,字符串的唯一部分将在结果匹配中

(?=\w+") - 预读单词字符,后跟 " `

请记住,lookbehind 是相当新的。它适用于现代版本的 V8(包括 Chrome、Opera 和 Node),但not in most other environments,至少目前还没有。因此,虽然您可以在 Node 和您自己的浏览器中可靠地使用lookbehind(如果它在现代版本的 V8 上运行),但随机客户端(例如在公共网站上)还没有充分支持它。


刚刚进行了一次快速计时测试,输入的重要性令人印象深刻:jsfiddle.net/60neyop5
但是,例如,如果我想提取数字、倍数并“放回去”,我还必须对 \d+ 进行分组,对吗?
@MoshFeu 使用替换函数并使用整个匹配,数字:用 match => match * 2 替换第二个参数。数字仍然是整个匹配,因此不需要组
感谢分享。大约 75% 的浏览器支持,iOS Safari 中最明显的缺失:caniuse.com/js-regexp-lookbehind
J
Jogai

对马修的答案的一点改进可能是前瞻而不是最后一个捕获组:

.replace(/(\w+)(\d+)(?=\w+)/, "$1!NEW_ID!");

或者您可以按小数拆分并使用您的新 ID 加入,如下所示:

.split(/\d+/).join("!NEW_ID!");

此处的示例/基准:https://codepen.io/jogai/full/oyNXBX


E
Emma

也可以使用两个捕获组;我还包括两个破折号,作为附加的左右边界,在数字之前和之后,修改后的表达式看起来像:

(.*name=".+_)\d+(_[^"]+".*)

const 正则表达式 = /(.*name=".+_)\d+(_[^"]+".*)/g; const str = `some_data_before name="some_text_0_some_text" 然后 some_data after`; const subst = ` $1!NEW_ID!$2`; const 结果 = str.replace(regex, subst); console.log(result);

如果您想探索/简化/修改表达式,它已在 regex101.com 的右上角面板中进行了说明。如果您愿意,您还可以在此链接中观看它如何与一些示例输入匹配。

正则表达式电路

jex.im 可视化正则表达式:

https://i.stack.imgur.com/xYswa.png


C
CTS_AE

一个更简单的选择是只捕获数字并替换它们。

常量名称 = 'preceding_text_0_following_text';常量匹配器 = /(\d+)/; // 替换为你想要的任何内容 const newName = name.replace(matcher, 'NEW_STUFF'); console.log("完全替换", newName); // 使用函数对匹配和替换执行工作 // 在这种情况下,使用箭头函数递增它 const incrementedName = name.replace(matcher, (match) => ++match); console.log("增量", incrementedName);

资源

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace


В
Владислав Паршенцев
"some_text_0_some_text".replace(/(?=\w+)\d+(?=\w+)/, '!NEW_ID!')

结果是

some_text_!NEW_ID!_some_text

常量正则表达式 = /(?=\w+)\d+(?=\w+)/; const newID = '!NEW_ID!';常量 str = 'some_text_0_some_text';常量结果 = str.replace(regExp, newID);控制台.log(结果);

x(?=y) 在 JS 正则表达式中

仅当“x”后跟“y”时才匹配“x”。例如,/Jack(?=Sprat)/ 仅在其后跟“Sprat”时才匹配“Jack”。 /Jack(?=Sprat|Frost)/ 仅当其后跟“Sprat”或“Frost”时才匹配“Jack”。然而,“Sprat”和“Frost”都不是比赛结果的一部分。

details