您可以在回溯中使用反向引用吗?

假设我想在我后面的任何位置重复一个字符两次的split

    String REGEX1 = "(?<=(.)\\1)"; // DOESN'T WORK!
    String REGEX2 = "(?<=(?=(.)\\1)..)"; // WORKS!

    System.out.println(java.util.Arrays.toString(
        "Bazooka killed the poor aardvark (yummy!)"
        .split(REGEX2)
    )); // prints "[Bazoo, ka kill, ed the poo, r aa, rdvark (yumm, y!)]"

使用REGEX2(后向引用位于嵌套在lookbehind内的lookahead中)是可行的,但是REGEX1在运行时会出现此错误:
Look-behind group does not have an obvious maximum length near index 8
(?<=(.)\1)
        ^

我想这种说法是有道理的,因为一般而言,反向引用可以捕获任意长度的字符串(但是,如果regex编译器更聪明,则在这种情况下,它可以确定\1(.),因此长度有限) )。

那么,有没有一种方法可以在回溯中使用反向引用?

如果没有,您是否可以始终使用此嵌套先行方法解决它?还有其他常用技术吗?

最佳答案

看起来您的怀疑是正确的,因为反向引用通常不能在Java lookbehinds中使用。您提出的解决方法使后视的有限长度变得明确,并且对我来说看起来非常聪明。

我很想知道Python如何使用此正则表达式。 Python仅支持固定长度的向后查找,而不像Java一样支持有限长度,但是此正则表达式为固定长度。我不能直接使用re.split(),因为Python的re.split()从未在空匹配中 split ,但我认为我在re.sub()中发现了一个错误:

>>> r=re.compile("(?<=(.)\\1)")
>>> a=re.sub(r,"|", "Bazooka killed the poor aardvark (yummy!)")
>>> a
'Bazo|oka kil|led the po|or a|ardvark (yum|my!)'

后向匹配项是两个重复字符之间的匹配!

09-08 06:07