为啥在正则表达式中以某种方式忽略子后的第一个字符? [复制]

Posted

技术标签:

【中文标题】为啥在正则表达式中以某种方式忽略子后的第一个字符? [复制]【英文标题】:Why the first character after a sub is ignored somehow in the regex? [duplicate]为什么在正则表达式中以某种方式忽略子后的第一个字符? [复制] 【发布时间】:2020-03-09 22:05:59 【问题描述】:

这是我在 Chrome 78 控制台中得到的。

console.log('1111'.replace(/(^|[^2])/g, '$12'))
// output "21121212"

为什么不将第一个 1 替换为 12

【问题讨论】:

您期待什么结果? $1 是对捕获的匹配项的引用。 我认为想要的输出是212121212 @YongQuan 是的,我也是这么想的,但是我测试了OP代码,实际上输出是21121212 JS 正则表达式在零长度匹配后跳过当前位置是一个已知问题,请参阅链接线程并详细解释根本原因。 【参考方案1】:

我认为发生的事情是在替换零宽度匹配后,它会在搜索下一个匹配之前将输入字符串中的位置增加 1。否则,它会陷入无限循环,不断匹配和替换相同的零宽度字符串。

由于^ 在开头匹配一个零宽度的字符串,它会增加位置,在寻找下一个匹配之前跳过字符串的第一个字符。

【讨论】:

【参考方案2】:

方法一

我猜你正在尝试写作

(?<=^)|([^2])

但是,您需要检查是否支持环视。

Demo 1


方法二

这个方法也有lookarounds,

(?<=^|[^2])

Demo 2

如果您要提供一些示例输入和输出,可能会有一些解决方法。

例如,一个积极的前瞻可能是一个可供选择的选项:

(?=^|[^2]|$)

Demo 3


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


正则表达式电路

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

【讨论】:

如果您从 PCRE 切换到 ECMAScript,您的演示将无法运行。 很遗憾,ECMAScript 不支持lookbehind

以上是关于为啥在正则表达式中以某种方式忽略子后的第一个字符? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

初学js正则

python-正则表达式

正则表达式re模块

JavaScript 正则表达式

正则表达式

与正则表达式匹配时是不是可以忽略字符串中的字符