Expresiones Regex en Java, \\ s frente a \\ s +

96

¿Cuál es la diferencia entre las siguientes dos expresiones?

x = x.replaceAll("\\s", "");
x = x.replaceAll("\\s+", "");
mpluse
fuente
3
Cuantificadores, lea sobre ellos.
jn1kk

Respuestas:

88

El primero coincide con un solo espacio en blanco, mientras que el segundo coincide con uno o varios espacios en blanco. Son los llamados cuantificadores de expresión regular y realizan coincidencias como esta (tomadas de la documentación ):

Greedy quantifiers
X?  X, once or not at all
X*  X, zero or more times
X+  X, one or more times
X{n}    X, exactly n times
X{n,}   X, at least n times
X{n,m}  X, at least n but not more than m times

Reluctant quantifiers
X?? X, once or not at all
X*? X, zero or more times
X+? X, one or more times
X{n}?   X, exactly n times
X{n,}?  X, at least n times
X{n,m}? X, at least n but not more than m times

Possessive quantifiers
X?+ X, once or not at all
X*+ X, zero or more times
X++ X, one or more times
X{n}+   X, exactly n times
X{n,}+  X, at least n times
X{n,m}+ X, at least n but not more than m times
Óscar López
fuente
20
Siempre me ha gustado cómo proporcionan descripciones separadas de las versiones codiciosa, reacia y posesiva de cada cuantificador, y luego dicen exactamente lo mismo sobre los tres. ;)
Alan Moore
60

Esas dos replaceAllllamadas siempre producirán el mismo resultado, independientemente de cuál xsea. Sin embargo, es importante tener en cuenta que las dos expresiones regulares no son iguales:

  • \\s - coincide con un solo carácter de espacio en blanco
  • \\s+ - coincide con la secuencia de uno o más caracteres de espacio en blanco.

En este caso, no importa, ya que está reemplazando todo con una cadena vacía (aunque sería mejor usarla \\s+desde el punto de vista de la eficiencia). Si estuviera reemplazando con una cadena no vacía, los dos se comportarían de manera diferente.

arshajii
fuente
Escriba su primera línea, si x es "Reserve su dominio y consiga \ n \ n \ n \ n \ n \ n en línea hoy". ¿Ambos producirán los mismos resultados?
sofs1
3
@ user3705478 Ambos producirán los mismos resultados, incluso si hubiera varios espacios uno después del otro. La diferencia radica en la forma en que se maneja. Si tuviera un grupo de (por ejemplo) 3 espacios directamente uno detrás del otro \\ s + toma ese grupo y lo convierte en un "", mientras que \\ s procesaría cada espacio por sí solo.
Dennie
11

En primer lugar, debe comprender que la salida final de ambas declaraciones será la misma, es decir, eliminar todos los espacios de la cadena dada.

Sin embargo x.replaceAll("\\s+", "");, será una forma más eficiente de recortar espacios (si la cadena puede tener múltiples espacios contiguos) debido a que potencialmente hay menos reemplazos debido al hecho de que regex\\s+ coincide con 1 o más espacios a la vez y los reemplaza con una cadena vacía.

Entonces, aunque obtenga el mismo resultado de ambos, es mejor usar:

x.replaceAll("\\s+", "");
anubhava
fuente
2

La primera expresión regular coincidirá con un carácter de espacio en blanco. La segunda expresión regular coincidirá a regañadientes con uno o más caracteres de espacio en blanco. Para la mayoría de los propósitos, estas dos expresiones regulares son muy similares, excepto en el segundo caso, la expresión regular puede coincidir con más de la cadena, si evita que la coincidencia de expresiones regulares falle. de http://www.coderanch.com/t/570917/java/java/regex-difference

evgenyl
fuente
Tacha la palabra "a regañadientes". Esta pregunta es sobre \s+, no \s+?como la otra pregunta.
Alan Moore