gpt4 book ai didi

javascript - 正则表达式仅捕获匹配中捕获组的最后一个实例

转载 作者:数据小太阳 更新时间:2023-10-29 05:58:19 25 4
gpt4 key购买 nike

我在两种不同的语言(JavaScript 和 Flash)中使用以下正则表达式产生相同的奇怪结果。我想知道的不是如何修复它,而是为什么会出现这种行为?

正则表达式:

\[(\\{2}|\\\]|[^\]])*\]

这里的目标是匹配括号内的字符串,并确保我不会在转义的括号处停止。

如果我有文本输入 [abcdefg] 它是正确匹配的,但作为捕获组的一部分返回的唯一内容是 g,正如我所期望的那样 abcdefg。如果我将表达式更改为\[((?:\\{2}|\\\]|[^\]])*)\],然后我得到我想要的结果。

那么为什么会这样呢?这在其他语言中是否一致?

注意:将表达式简化为 \[([^\]])*\] 会产生同样的问题。

最佳答案

不管问题如何,ActionScript 和 JavaScript 应该始终产生相同的结果,因为它们都实现了 ECMAScript(或其超集,但对于正则表达式它们不应该不一致)。

但是,是的,这将以任何语言(或者更确切地说是任何正则表达式风格)发生。原因是您正在重复捕获组。让我们举一个更简单的例子:将 (.)*abc 匹配。所以我们要重复的是(.)。第一次尝试时,引擎进入组,将 a. 匹配,离开组并捕获 a。直到现在量词才起作用,它重复了整个过程。于是我们再次入组,匹配捕获b。此捕获覆盖了前一个,因此 \1 现在包含 b。第三次重复同样如此:捕获将被 c 覆盖。

我不知道有哪一种正则表达式有不同的表现,唯一能让您访问所有以前的捕获(而不是仅仅覆盖它们)的是 .NET。

解决方案是 p.s.w.g.建议的。使重复非捕获所需的分组(这将提高性能,因为无论如何您都不需要所有捕获和覆盖)并将整个事物包装在一个新组中。你的表达虽然有一个小缺陷:你需要在否定字符类中包含反斜杠。否则,回溯可能会在 [abc\] 中为您提供匹配项。所以这里有一个表达式可以如您所愿地工作:

\[((?:\\{2}|\\\]|[^\]\\])*)\]

Working demo. (不幸的是,它没有显示捕获,但它表明它在所有情况下都给出了正确的匹配)

请注意,您的表达式不允许使用其他转义序列。特别是单个 \ 后跟除 ] 以外的任何内容都会导致您的模式失败。如果这不是您想要的,您可以使用:

\[((?:\\.|[^\]\\])*)\]

Working demo.

使用 "unrolling-the-loop" 可以进一步提高性能技术:

\[([^\]\\]*(?:\\.[^\]\\]*)*)\]

Working demo.

关于javascript - 正则表达式仅捕获匹配中捕获组的最后一个实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17393683/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com