12

後読みで後方参照を使用できますか?

split私の後ろのどこにいても、キャラクターが2回繰り返されたいとしましょう。

    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(後方参照が後読み内にネストされた先読みにある場合) は機能しますがREGEX1、実行時に次のエラーが発生します。

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

一般に、後方参照は任意の長さの文字列をキャプチャできるため、この種の\1ことは理にかなっていると思います (ただし、正規表現コンパイラが少し賢ければ、この場合は(.)長さが有限であると判断できます)。

では、後読みで後方参照を使用する方法はありますか?

そうでない場合は、このネストされた先読みを使用して常に回避できますか? 他によく使われるテクニックはありますか?

4

1 に答える 1

5

後方参照は一般にJavaの後読みでは使用できないというあなたの疑いは正しいようです。あなたが提案した回避策は、後読みの有限の長さを明示的にし、私には非常に巧妙に見えます。

Python がこの正規表現で何をするのか、興味をそそられました。Python は固定長の後読みのみをサポートし、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!)'

重複する 2 つの文字で後読みが一致します。

于 2010-04-29T07:59:13.240 に答える