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