2012-06-07 20 views
6

¿Cómo se relaciona más de un carácter de espacio en Java regex?Java Regex: cómo hacer coincidir uno o más caracteres de espacio

Tengo una expresión regular que estoy tratando de hacer coincidir. La expresión regular falla cuando tengo dos o más caracteres espaciales.

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' =>' Patrón de cadena' en las convenciones de codificación estándar de Java. – assylias

+2

¿Es eso ... la sintaxis php en código Java? – ean5533

+3

Podría ser que el segundo espacio coincida con [^ a] (un espacio no es una 'a') – erikxiv

Respuesta

12

El problema es realmente debido a backtracking. Su expresión regular:

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

dice que "la fruta, seguido de uno o más espacios, seguido de uno o más caracteres 'a' no, seguido de uno o más caracteres 'palabra'". La razón por la que esto falla con dos espacios es porque \s+ coincide con el primer espacio, pero luego devuelve el segundo, que luego satisface el [^a]+ (con el segundo espacio) y la parte \s+ (con el primero).

Creo que puede solucionarlo simplemente utilizando el cuantificador posessive en su lugar, que sería \s++. Esto le dice al \sno para devolver el segundo carácter de espacio. Puede encontrar la documentación sobre los cuantificadores de Java here.


A modo de ejemplo, aquí hay dos ejemplos: en Rubular

(resultados esperados da, de lo que describes)
  1. Using the possessive quantifier on \s
  2. Your current regex with separate groupings around [^a\]+ and \w+. Observe que el segundo grupo de coincidencia (que representa el [^a]+) está capturando un segundo carácter de espacio.
+0

Corrija el análisis y una solución válida. Una segunda solución posible sería cambiar '[^ a]' a '[^ a \ s]'. – ean5533

+0

@eldarerathis Su solución \\ s ++ funciona. – MontrealDevOne

Cuestiones relacionadas