35

URI に一致する 2 つの正規表現を作成しようとしています。これらの URI の形式は次のとおりです/foo/someVariableData/foo/someVariableData/bar/someOtherVariableData

2 つの正規表現が必要です。それぞれが 1 つに一致する必要がありますが、もう 1 つには一致する必要はありません。

私が最初に思いついた正規表現は /foo/.+/foo/.+/bar/.+それぞれ次のとおりです。

2番目の正規表現は問題ないと思います。2 番目の文字列にのみ一致します。ただし、最初の正規表現は両方に一致します。それで、私は(初めて)否定的な先読みをいじり始めました。私は正規表現を設計し、/foo/.+(?!bar)それをテストするために次のコードをセットアップしました

public static void main(String[] args) {
    String shouldWork = "/foo/abc123doremi";
    String shouldntWork = "/foo/abc123doremi/bar/def456fasola";
    String regex = "/foo/.+(?!bar)";
    System.out.println("ShouldWork: " + shouldWork.matches(regex));
    System.out.println("ShouldntWork: " + shouldntWork.matches(regex));
}

もちろん、どちらも に解決されtrueます。

私が間違っていることを知っている人はいますか?必ずしも否定先読みを使用する必要はありません。問題を解決する必要があるだけであり、否定先読みはそれを行う 1 つの方法かもしれないと思います。

ありがとう、

4

1 に答える 1

63

試す

String regex = "/foo/(?!.*bar).+";

またはおそらく

String regex = "/foo/(?!.*\\bbar\\b).+";

/foo/baz/crowbarsその正規表現を一致させたいと私が思うようなパスでの失敗を避けるため。

説明: (Javaストリングに必要な二重円記号なし)

/foo/ # Match "/foo/"
(?!   # Assert that it's impossible to match the following regex here:
 .*   #   any number of characters
 \b   #   followed by a word boundary
 bar  #   followed by "bar"
 \b   #   followed by a word boundary.
)     # End of lookahead assertion
.+    # Match one or more characters

\b、「単語境界アンカー」は、英数字と英数字以外の文字の間(または文字列の開始/終了と英数字の間)の空のスペースに一致します。したがって、inの前bまたは後に一致しますが、との間では一致しません。r"bar"wb"crowbar"

ヒント: http: //www.regular-expressions.infoをご覧ください-優れた正規表現チュートリアルです。

于 2012-06-20T18:03:52.433 に答える