Java正则表达式组否定是否可能?

5
我有以下正则表达式:(["'])(\\\1|[^\1])+\1
显然它不能被编译,因为[^\1]是非法的。
是否有可能否定一个匹配组?

1
你想匹配的文本是什么?你的正则表达式有点令人困惑。 - beerbajay
问题是,其他版本/语言是否也可以实现?我可以想象这样的结构可能没有意义,因为捕获组可以包含多个字符,所以[^\1]将是这些字符的列表...但这只是我的看法。也可能只是正则表达式引擎必须事先知道要期望哪些字符。[\1]能行吗? - Felix Kling
我只在regular-expression.info上找到了这个信息: "回溯引用也不能在字符类中使用。在大多数正则表达式中,像(a)[\1b]这样的正则表达式中的\1将被解释为八进制转义。因此,这个正则表达式将匹配一个后面跟着\x01ba。" 如果你想更深入地了解正则表达式,我建议阅读Mastering Regular Expressions by Jeffrey Friedl - Felix Kling
问题是:在Java正则表达式中是否可能否定已匹配的组?[^\1]只是用来说明我想否定索引为1的组。 - Savva Mikhalevski
1个回答

4

在正或负字符类中,无法使用向后引用。

但是您可以通过使用负面的前瞻断言来实现您想要的效果:

(["'])(?:\\.|(?!\1).)*\1

解释:

(["'])    # Match and remember a quote.
(?:       # Either match...
 \\.      # an escaped character
|         # or
 (?!\1)   # (unless that character is identical to the quote character in \1)
 .        # any character
)*        # any number of times.
\1        # Match the corresponding quote.

你在另一个问题中评论说它不起作用。那 (["'])(\\\1|.)+?\1 呢?难道不应该从左到右匹配交替项吗?还是我在这里错过了问题?在 JavaScript 中似乎没问题。 - Felix Kling
@FelixKling:你说得对。把括号移到正确的位置确实解决了问题。让我们看看能否恢复Ademiban的答案。 - Tim Pietzcker
投票以撤销删除。您的解决方案可能仍然更好,因为它避免了回溯。 - Felix Kling
@FelixKling:我不确定性能如何。它需要在每个位置进行前瞻,而不是回溯。我猜这比在堆栈上存储回溯位置要快一些,但可能并不会快很多。我更喜欢它,因为它更加明确。 - Tim Pietzcker

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接