12

您可以在后视中使用反向引用吗?

假设我想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)
        ^

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

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

如果没有,您是否可以始终使用这种嵌套的前瞻来解决它?还有其他常用的技术吗?

4

1 回答 1

5

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

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

两个重复字符之间的后视匹配!

于 2010-04-29T07:59:13.240 回答