2011-06-10 55 views
9

¿Por qué este código arroja una InputMismatchException? coincide con¿Por qué "hello \ s * world" no coincide con "hello world"?

Scanner scanner = new Scanner("hello world"); 
System.out.println(scanner.next("hello\\s*world")); 

La misma expresión regular en http://regexpal.com/ (con \ s en lugar de \\ s)

+2

http://regexpal.com/ pruebas javascript expresiones regulares, expresiones regulares no java. Puede intentar usar http://www.fileformat.info/tool/regex.htm para probar expresiones regulares de Java. – Marcelo

+0

@Marcelo mi probador de expresiones regex Java en línea favorito: http://www.regexplanet.com/simple/ –

+0

@Matt Gracias, lo marqué como favorito para la próxima vez que lo necesite. – Marcelo

Respuesta

11

un escáner, en contraposición a un Matcher, ha construido en la tokenización de la cadena, el delimitador predeterminado es el espacio en blanco . Entonces, su "mundo de hola" se está convirtiendo en "mundo" hello antes de que se dispute el partido. Sería un partido si ha cambiado el delimitador antes de escanear a algo que no es en la cadena, por ejemplo .:

Scanner scanner = new Scanner("hello world"); 
scanner.useDelimiter(":"); 
System.out.println(scanner.next("hello\\s*world")); 

pero parece que realmente para el caso de que solo debe utilizar un Matcher.

Este es un ejemplo del uso de un escáner "según lo previsto":

Scanner scanner = new Scanner("hello,world,goodnight,moon"); 
    scanner.useDelimiter(","); 
    while (scanner.hasNext()) { 
    System.out.println(scanner.next("\\w*")); 
    } 

salida sería

hello 
world 
goodnight 
moon 
+0

¿Y si la cadena es hola: mundo entonces ?! No debe hacer suposiciones sobre lo que está en su entrada: S –

+0

¿Cómo es relevante para ilustrar a Navin por qué su código no funciona?Dije: "Sería una coincidencia si:" no "Sería el código estrictamente correcto adecuado para el uso de producción si:" Se supone que la entrada es "Hola mundo";) – Affe

+0

Podría haber establecido un delimitador vacío en lugar de a: –

-1

Un escáner tiene un delimitador predeterminado de \\s+ Si sólo se desea detectar hello\\s*world , simplemente llame al scanner.useDelimiter("hello\\s*world")) y luego solo scanner.next();

Alternativa ley, puede llamar scanner.useDelimiter('any (escaped) char that would not occur in your text ') y utilizar scanner.next("hello\\s*world"))

Como nota al margen, si se desea que tenga al menos 1 espacio, desea utilizar un + en lugar de un *

+0

Esto no funciona. delimitador de "" tokenizes en h e l l o '' w o r d. – Affe

+0

Ya he editado eso :) Necesitas usar algún personaje que ciertamente no está en tu entrada. Tenga en cuenta que algunos caracteres son caracteres especiales de expresiones regulares, y que tendría que escapar de ellos para poder usarlos. Un personaje seguro que siempre uso es # –

1

El constructor del escáner toma una Patrón opcional que se usa para dividir la secuencia de entrada en tokens. Por defecto, es un patrón de espacio en blanco.

Scanner # next devuelve el siguiente token, si coincide con el patrón dado. En otras palabras, el patrón que pase a #next puede no contener espacios en blanco por defecto.

Puede invocar #useDelimiter para configurar el escáner para su caso de uso.

2

El delimitador predeterminado de un escáner son espacios en blanco, por lo que el escáner ve dos elementos hola y mundo. Y hello \ s + world no coincide con hello, por lo tanto, se lanza una excepción NoSuchElement.

2

Estas entradas funcionan:

"C:\Program Files\Java\jdk1.6.0_21\bin\java" RegexTest hello\s+world "hello  world" 
'hello  world' does match 'hello\s+world' 

Aquí está el código:

import java.util.regex.Matcher; 
import java.util.regex.Pattern; 

public class RegexTest { 

    public static void main(String[] args) { 

     if (args.length > 0) { 
      Pattern pattern = Pattern.compile(args[0]); 

      for (int i = 1; i < args.length; ++i) { 
       Matcher matcher = pattern.matcher(args[i]); 
       System.out.println("'" + args[i] + "' does " + (matcher.matches() ? "" : "not ") + "match '" + args[0] +"'"); 
      } 
     } 
    } 

}