2010-12-15 10 views
178

Estoy tratando de entender la diferencia entre matches() y find().Diferencia entre matches() y find() en Java Regex

De acuerdo con el Javadoc, (por lo que entiendo), matches() buscará la cadena completa, incluso si encuentra lo que está buscando, y find() se detendrá cuando encuentre lo que está buscando.

Si esa suposición es correcta, no puedo ver cada vez que desee utilizar matches() en lugar de find(), a menos que desee contar el número de coincidencias que encuentra.

En mi opinión, la clase String debería tener find() en lugar de matches() como método incorporado.

Entonces, para resumir:

  1. ¿Es mi suposición correcta?
  2. ¿Cuándo es útil usar matches() en lugar de find()?
+2

Tenga en cuenta que al llamar 'find()' varias veces puede devolver resultados diferentes para el mismo 'Matcher'. Ver mi respuesta a continuación. –

Respuesta

226

matches intenta hacer coincidir la expresión en contra de toda la cadena e implícitamente añadir un ^ al principio y $ al final de su patrón, lo que significa que no va a buscar una subcadena. Por lo tanto la salida de este código:

public static void main(String[] args) throws ParseException { 
    Pattern p = Pattern.compile("\\d\\d\\d"); 
    Matcher m = p.matcher("a123b"); 
    System.out.println(m.find()); 
    System.out.println(m.matches()); 

    p = Pattern.compile("^\\d\\d\\d$"); 
    m = p.matcher("123"); 
    System.out.println(m.find()); 
    System.out.println(m.matches()); 
} 

/* output: 
true 
false 
true 
true 
*/ 

123 es una subcadena de a123b por lo que los find() salidas verdadero método. matches() solo 've' a123b que no es lo mismo que 123 y por lo tanto salidas falsas.

+12

Esta respuesta es engañosa. 'matchers()' no es simplemente un 'find()' con un entorno implícito^y $. Tenga en cuenta que llamar '.find()' más de una vez puede tener diferentes resultados si no es precedido por 'reset()', mientras 'matches()' siempre devolverá el mismo resultado. Ver mi respuesta a continuación. –

61

matches devuelve verdadero si toda la cadena coincide con el patrón dado. find intenta encontrar una subcadena que coincida con el patrón.

+27

Podría decir que 'matches (p)' es lo mismo que 'find ("^"+ p +" $ ")' si eso está más claro. – jensgram

+3

Solo un ejemplo para aclarar la respuesta: "[a-z] +" con la cadena "123abc123" fallará al usar coincidencias() pero tendrá éxito usando find(). – bezmax

+3

@Max Exactamente, '" 123abc123 ".matches (" [a-z] + ")' fallará como '" 123abc123 ".find ("^[a-z] + $ ")' haría. Mi punto era que 'matches()' funciona para una coincidencia completa, al igual que 'find()' con los anclajes de inicio y fin. – jensgram

34

matches() solo devolverá verdadero si la cadena completa coincide. find() intentará encontrar el siguiente ocurrencia dentro de la subcadena que coincide con la expresión regular. Tenga en cuenta el énfasis en "el próximo". Eso significa que el resultado de llamar al find() varias veces puede no ser el mismo. Además, al usar find() puede llamar al start() para devolver la posición con la que coincidió la subcadena.

final Matcher subMatcher = Pattern.compile("\\d+").matcher("skrf35kesruytfkwu4ty7sdfs"); 
System.out.println("Found: " + subMatcher.matches()); 
System.out.println("Found: " + subMatcher.find() + " - position " + subMatcher.start()); 
System.out.println("Found: " + subMatcher.find() + " - position " + subMatcher.start()); 
System.out.println("Found: " + subMatcher.find() + " - position " + subMatcher.start()); 
System.out.println("Found: " + subMatcher.find()); 
System.out.println("Found: " + subMatcher.find()); 
System.out.println("Matched: " + subMatcher.matches()); 

System.out.println("-----------"); 
final Matcher fullMatcher = Pattern.compile("^\\w+$").matcher("skrf35kesruytfkwu4ty7sdfs"); 
System.out.println("Found: " + fullMatcher.find() + " - position " + fullMatcher.start()); 
System.out.println("Found: " + fullMatcher.find()); 
System.out.println("Found: " + fullMatcher.find()); 
System.out.println("Matched: " + fullMatcher.matches()); 
System.out.println("Matched: " + fullMatcher.matches()); 
System.out.println("Matched: " + fullMatcher.matches()); 
System.out.println("Matched: " + fullMatcher.matches()); 

salida será:

 
Found: false 
Found: true - position 4 
Found: true - position 17 
Found: true - position 20 
Found: false 
Found: false 
Matched: false 
----------- 
Found: true - position 0 
Found: false 
Found: false 
Matched: true 
Matched: true 
Matched: true 
Matched: true 

Por lo tanto, tenga cuidado al llamar find() varias veces si el objeto Matcher no se restablece, incluso cuando la expresión regular está rodeado de ^ y $ para que coincida con la cadena completa.

2

matches(); no almacena en el búfer, pero find() almacena en el búfer. find() busca primero el final de la cadena, indiza el resultado y devuelve el valor booleano y el índice correspondiente.

Por eso, cuando usted tiene un código como

1:Pattern.compile("[a-z]"); 

2:Pattern.matcher("0a1b1c3d4"); 

3:int count = 0; 

4:while(matcher.find()){ 

5:count++: } 

En 4: El motor de expresiones regulares usando la estructura patrón se lee a través de la totalidad de su código (un índice a otro según lo especificado por el regex[single character] a encuentre al menos una coincidencia. Si se encuentra dicha coincidencia, se indexará y luego el bucle se ejecutará en función del resultado indexado; de lo contrario, si no hiciera cálculos anticipados como matches(), no lo hará. primer carácter de la cadena coincidente no es un alfabeto.

2

find() considerará la subcadena contra la expresión regular donde como matches() considerará la expresión completa.

find() devolverá verdadero solo si la subcadena de la expresión coincide con el patrón.

public static void main(String[] args) { 
     Pattern p = Pattern.compile("\\d"); 
     String candidate = "Java123"; 
     Matcher m = p.matcher(candidate); 

     if (m != null){ 
      System.out.println(m.find());//true 
      System.out.println(m.matches());//false 
     } 
    } 
Cuestiones relacionadas