Java 正则表达式错误 - 使用组参考进行后视

Posted

技术标签:

【中文标题】Java 正则表达式错误 - 使用组参考进行后视【英文标题】:Java regex error - Look-behind with group reference 【发布时间】:2013-05-15 06:26:31 【问题描述】:

我正在尝试构建一个正则表达式,它与一个类中出现的两次字符完全匹配。这是我制作的正则表达式:

(?<!\1)([^raol1c])\1(?!\1)

如您所见,它使用负片前瞻和后视。但是,像往常一样,后者不起作用;当它明显具有最大长度(恰好是一个字符)时,java 会抛出众所周知的异常“后视组没有明显的最大长度”。

理想情况下,正则表达式应匹配“hh”、“jhh”、“ahh”、“hhj”、“hha”,但不匹配“hhh”。

关于如何处理这个问题并制定解决方法的任何想法?

【问题讨论】:

你检查的字符串有固定长度吗? 不,字符串可以是任意长度。 我不明白你的规则:"hhaa" 应该匹配吗? 是的。因为正则表达式匹配“hh”,然后向前寻找“h”的否定匹配,并在后面寻找“h”的否定匹配,这两种情况都是正确的。 对于单个正则表达式之外的非常简单的解决方法,搜索 ([^raol1c])\1+ 并检查结果是否不超过两个字符。 【参考方案1】:

这是一种解决方法。它很丑,但显然它有效:

(?<!(?=\1).)([^raol1c])\1(?!\1)

将反向引用放入lookbehind内的零长度lookahead中,使得lookbehind肯定具有固定长度。

免责声明,我没有想到这个(很遗憾):Backreferences in lookbehind

编辑:

由于某种原因,上述模式不排除hhh。但是,这是可行的:

(?<!(.)(?=\1))([^raol1c])\2(?!\2)

如果我们在lookbehind 中创建第一个组,那么我们可以使用它来确保lookbehind 之后的第一个字符与它之前的不同。

Working demo.

【讨论】:

好一个。与 Matcher.matches() 一起使用。 代码Pattern.compile("(?&lt;!(?=\\1).)([^raol1c])\\1(?!\\1)").matcher("hhh").find() 返回true 但应该是false。它还返回带有“hh”的true @user2402372 我有一个工作版本。稍后编辑。 这可以降低 1 个字符:([^raol1c])(?&lt;!(?=\1)..)\1(?!\1)

以上是关于Java 正则表达式错误 - 使用组参考进行后视的主要内容,如果未能解决你的问题,请参考以下文章

查找连续重复单词时的Python后视正则表达式“固定宽度模式”错误

Javascript 正则表达式(负)后视在 Firefox 中不起作用

正则表达式替换文本,除非它前面有反斜杠而不使用后视

复杂的 (PHP) 正则表达式,具有积极的后视能力

求正则表达式, 第一位大于0的正整数,直接可以在onkeyup事件中 使用的!

求java正则表达式输出小于10的正整数