8

Java正規表現で複数のスペース文字をどのように照合しますか?

一致させようとしている正規表現があります。スペース文字が2つ以上あると、正規表現が失敗します。

public static void main(String[] args) { 
    String pattern = "\\b(fruit)\\s+([^a]+\\w+)\\b"; //Match 'fruit' not followed by a word that begins with 'a'
    String str = "fruit apple"; //One space character will not be matched
    String str_fail = "fruit  apple"; //Two space characters will be matched
    System.out.println(preg_match(pattern,str)); //False (Thats what I want)
    System.out.println(preg_match(pattern,str_fail)); //True (Regex fail)
}

public static boolean preg_match(String pattern,String subject) {
    Pattern regex = Pattern.compile(pattern);
    Matcher regexMatcher = regex.matcher(subject);
    return regexMatcher.find();
}
4

1 に答える 1

12

問題は実際にはバックトラックが原因です。あなたの正規表現:

 "\\b(fruit)\\s+([^a]+\\w+)\\b"

「果物、1つ以上のスペース、1つ以上の非「a」文字、1つ以上の「単語」文字が続く」と言います。これが2つのスペースで失敗する理由は\s+、最初のスペースと一致するが、2番目のスペースを返し、[^a]+(2番目のスペースで)と\s+部分(最初のスペースで)を満たすためです。

代わりに、ポーズをとる数量詞を使用するだけで修正できると思います\s++。これは、2番目のスペース文字を返さ\s ないように指示します。Javaの数量詞に関するドキュメントはここにあります


例として、Rubularでの2つの例を次に示します。

  1. 所有格の数量詞を使用する\s(あなたが説明したことから期待される結果を与える)
  2. [^a\]+との周りに別々のグループがある現在の正規表現\w+。2番目の一致グループ(を表す[^a]+)が2番目のスペース文字をキャプチャしていることに注意してください。
于 2012-06-07T15:00:32.167 に答える