背后的反向引用

时间:2010-04-29 05:34:38

标签: java regex lookbehind backreference

你能在后视镜中使用反向引用吗?

假设我想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中的前瞻)可行,但REGEX1在运行时出现此错误:

Look-behind group does not have an obvious maximum length near index 8
(?<=(.)\1)
        ^

这种有意义,我想,因为通常反向引用可以捕获任意长度的字符串(如果正则表达式编译器更聪明一点,它可以确定{{1在这种情况下,\1(.),因此长度有限。)

那么有没有办法在后视镜中使用反向引用?

如果没有,你可以使用这个嵌套的前瞻来解决它吗?还有其他常用技术吗?

1 个答案:

答案 0 :(得分:5)

看起来你的怀疑是正确的,反向引用通常不能用于Java lookbehinds。你提出的解决方法使得lookbehind的有限长度显而易见,对我来说看起来非常聪明。

我很想知道Python对这个正则表达式的作用。 Python只支持固定长度的lookbehind,而不是像Java这样的有限长度,但这个正则表达式是固定长度的。我无法直接使用re.split(),因为Python的re.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!)'

lookbehind匹配两个重复字符之间的