2012-06-07 14 views
6

Jak dopasować więcej niż jedną spację w wyrażeniu Java?Java Regex: Jak dopasować jeden lub więcej znaków spacji

Mam wyrażeń regularnych, które próbuję dopasować. Regex kończy się niepowodzeniem, gdy mam dwa lub więcej znaków spacji.

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(); 
} 
+1

'String $ pattern' =>' Wzór ciągu' w standardowych konwencjach kodowania Java. – assylias

+2

Czy to jest ... składnia PHP w kodzie Java? – ean5533

+3

Może być tak, że druga przestrzeń jest dopasowana przez [^ a] (spacja nie jest "a"). – erikxiv

Odpowiedz

12

Problem jest w rzeczywistości z powodu backtracking. Twój regex:

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

mówi „owoc, a następnie przez jeden lub więcej spacji, a następnie przez jeden lub więcej nie«A»znaków, a następnie przez jeden lub więcej znaków«słowo»”. Powodem tego jest to, że dwie spacje są nieudane, ponieważ \s+ dopasowuje pierwszą przestrzeń, ale następnie zwraca drugą wartość, która następnie spełnia warunek [^a]+ (z drugą przestrzenią) i część (z pierwszą).

Myślę, że można to naprawić, po prostu za pomocą kwantyfikatora posesyjnego zamiast, który byłby \s++. To mówi, że \s nie zwraca drugiej litery spacji. Dokumentację można znaleźć na kwantyfikatorach Javy here.


Jako przykład, oto dwa przykłady w Rubular:

  1. Using the possessive quantifier on \s (daje oczekiwanych rezultatów, z czego opisać)
  2. Your current regex with separate groupings around [^a\]+ and \w+. Zauważ, że druga grupa dopasowania (reprezentująca [^a]+) przechwytuje drugą spację.
+0

Prawidłowa analiza i prawidłowe rozwiązanie. Drugim możliwym rozwiązaniem jest zmiana '[^ a]' na '[^ a \ s]'. – ean5533

+0

@eldarerathis Twoje rozwiązanie \\ s ++ działa. – MontrealDevOne

Powiązane problemy