0

したがって、コメントをスキップしながら、トークンの最初のインスタンスを別のトークンに置き換える、変更された文字列を返す必要があります。これが私が話していることの例です:

This whole quote is one big String
-- I don't want to replace this @@
But I want to replace this @@!

元 .NET 開発者だったので、これは簡単だと思いました。次のように否定的な後読みを行うだけです。

(?<!--.*)@@

しかしその後、Java ではこれができないことを知りました。したがって、中括弧が問題ないことを知ったとき、私はこれを試しました:

(?<!--.{0,9001})@@

これは例外をスローしませんでしたが、コメントの @@ と一致しました。

この正規表現を Java 正規表現テスターでテストすると、期待どおりに動作します。私が思いつく唯一のことは、Java 1.5 を使用しているということです。Java 1.5 の正規表現エンジンにバグがある可能性はありますか? そうだとすると、Java 1.5 に、文字列を分割して再構築することなく、やりたいことをさせるにはどうすればよいでしょうか?

編集# を -- 演算子に変更しました。これは、正規表現が 1 つではなく 2 つの文字でより複雑になるように見えるためです。私は当初、「クエリをそのように変更するべきではありません!」というトピックから外れた議論を避けるために、クエリを変更していることを明らかにしませんでした。私がこれを行うのには非常に正当な理由があります。クエリ変更の推奨事項については議論しないでください。ありがとう

4

2 に答える 2

5

ここは本当に必要ありませんnegative look-behind。それがなくてもできます。

次のようになります。

String str = "I don't want to replace this @@";     
str = str.replaceAll("^([^#].*?)@@", "$1");

@@そのため、文字列内で で始まらない の最初の出現#箇所を の前の文字列の部分に置き換えます@@。したがって、@@削除されます。ここでは、消極的な量指定子-replaceAllを使用しているため機能します。そのため、最初の で自動的に停止します。.*?@@


コメントで@nhahtdhが正しく指摘しているように、コメントが行末にある場合、これは失敗する可能性があります。したがって、むしろこれを使用できます。

String str = "I don't want to # replace this @@";
str = str.replaceAll("^([^#]*?)@@", "$1");

これはどんな場合でも機能します。この例で@@は、コメントの一部であるため、 は置き換えられません。


コメントの開始が 2 文字で示されている場合、否定された文字クラスは機能しません。negative look-ahead次のように使用する必要があります。

String str = "This whole quote @@  is one big String -- asdf @@\n" +
             "-- I don't want to replace this @@\n" + 
             "But I want to replace this @@!";
str = str.replaceAll("(?m)^(((?!--).)*?)@@", "$1");

System.out.println(str);

出力:

This whole quote   is one big String -- asdf @@
-- I don't want to replace this @@
But I want to replace this !

(?m)パターンの先頭に を使用してMULTILINE一致モードを有効にするため、^は式全体の先頭ではなく、各行の先頭に一致します。

于 2013-02-14T19:50:40.660 に答える
0

次のようなものを使用できます。

String string = "This whole quote is one big String\n" +
                "# I don't want to replace this @@\n" +
                "And I also # don't want to replace this @@\n" +
                "But I want to replace this @@!\n" +
                "But not this @@!";

Matcher m =
    Pattern.compile (
        "^((?:[^@#]|@[^@]|#[^\n]*)*)@@", Pattern.MULTILINE).
            matcher (string);

StringBuffer result = new StringBuffer ();
if (m.find ())
    m.appendReplacement (result, "$1FOO");
m.appendTail (result);

System.out.println (result.toString ());
于 2013-02-14T19:58:25.370 に答える