0

を使用しようとしましuseTransparentBounds()たが、期待どおりに機能しないようです(ideoneで見られるように)。次のスニペットでは、m.find()透過的な境界が有効になっているため、一致するものが見つかると予想しました。これにより、Matcherがその領域の境界の外側を検索できるようになりました。なぜこれが機能しないのですか?

import java.util.regex.Matcher;
import java.util.regex.Pattern;

class Foo {
    public static void main(String[] args) {
        // match everything preceded by X
        Matcher m = Pattern.compile(".*(?<=X)").matcher("Foo BarX Baz");

        // limit matcher to first chars outside of normal lookahead scope
        m.region(0, 4);

        // matcher should still find a match because of transparent bounds
        m.useTransparentBounds(true);

        // this fails to find a match! why?
        System.out.println("found=" + m.find());
        System.out.println("result=" + m.group());
    }
}

(Mac OSX MountainLionでJ2SE6(1.6.0_37-b06-434-11M3909)を使用しています)

4

2 に答える 2

1

まず、(?<=X)先読みではなく、後読みです。私はあなたが意味したと思います.*(?=X)。それでは、一致する領域を制限しないとどうなるかを調べることから始めましょう。

最初に、.*文字列全体()を消費し、次に制御を(先読み)に"Foo BarX Baz"渡します。これにより、次の文字が。であることが表明されます。それは(明らかに)失敗するので、マッチャーは最後の文字を返し、ちょうど消費しようとしますが、彼は先読みが再び失敗します。それが消費するポイントに達するまで、それはそのように続きます。次の文字はになりましたので、先読みは成功します。(?=X)X"Foo BarX Ba""Foo Bar"X

リージョンを制限(0,7)すると、引き続き機能することが期待できます。 あなたは次のキャラクターがであることを知っていXます、そしてとにかく、あなたはそれを消費するのではなく、見ようとしているだけです。Xしかし、いいえ、マッチャーはそれを見ることさえできません。最初に適用した場合とまったく同じように動作"Foo Bar"します。の後に文字がrないと信じているので、後の文字を気にする必要はありません。

とにかく、これがデフォルトの動作です。useTransparentBounds(true)ゼロ幅アサーション(ルックアラウンド、単語境界など)を照合する目的で、マッチャーが領域の境界を超えて検索できるようにします。現在の地域にないものはまだ消費できません。それはそれが何のためであるかではありません。

正規表現が機能しない理由は、文字列の最初の4文字のみを参照しているためです。先読みが成功するにはX、インデックス#4(例"Foo X")が必要です。

于 2012-12-23T11:54:49.893 に答える
0

これは0-4、一致する領域ではない領域を指定したためです。

つまり、m.region(0,7);

これは、 0〜4ではなく0〜7の範囲にあるもの0-7と一致するはずです。Foo BarX

しかし、あなたは何を一致させようとしています!あなたの正規表現は意味がありません

于 2012-12-23T05:59:04.373 に答える