Expressões regex em Java, \\ s vs. \\ s +

96

Qual é a diferença entre as duas expressões a seguir?

x = x.replaceAll("\\s", "");
x = x.replaceAll("\\s+", "");
mpluse
fonte
3
Quantificadores, leia sobre eles.
jn1kk

Respostas:

88

O primeiro corresponde a um único espaço em branco, enquanto o segundo corresponde a um ou mais espaços em branco. Eles são os chamados quantificadores de expressão regular e realizam correspondências como esta (retiradas da documentação ):

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
fonte
20
Sempre adorei como eles fornecem descrições separadas das versões gananciosas, relutantes e possessivas de cada quantificador, e depois dizem exatamente a mesma coisa sobre os três. ;)
Alan Moore,
60

Essas duas replaceAllchamadas sempre produzirão o mesmo resultado, independentemente do que xseja. No entanto, é importante observar que as duas expressões regulares não são iguais:

  • \\s - corresponde a um único caractere de espaço em branco
  • \\s+ - corresponde à sequência de um ou mais caracteres de espaço em branco.

Nesse caso, não faz diferença, já que você está substituindo tudo por um string vazio (embora seja melhor usar \\s+do ponto de vista da eficiência). Se você estivesse substituindo por uma string não vazia, os dois se comportariam de maneira diferente.

Arshajii
fonte
Escreva sua primeira linha, se x for "Reserve seu domínio e coloque \ n \ n \ n \ n \ n \ n online hoje." Ambos produzirão os mesmos resultados?
sofs1
3
@ user3705478 Ambos produzirão os mesmos resultados, mesmo que haja vários espaços um após o outro. A diferença está na forma como é tratada. Se você tivesse um grupo de (por exemplo) 3 espaços seguindo diretamente um ao outro, \\ s + pega aquele grupo e transforma o todo em um "", enquanto \\ s processa cada espaço por conta própria.
Dennie
11

Em primeiro lugar, você precisa entender que a saída final de ambas as instruções será a mesma, ou seja, remover todos os espaços de uma determinada string.

No entanto, x.replaceAll("\\s+", "");será uma maneira mais eficiente de cortar espaços (se a string puder ter vários espaços contíguos) por causa do potencial menor número de substituições devido ao fato de que regex \\s+corresponde a 1 ou mais espaços de uma vez e os substitui por string vazia.

Portanto, embora você obtenha a mesma saída de ambos, é melhor usar:

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

A primeira regex corresponderá a um caractere de espaço em branco. A segunda regex irá relutantemente corresponder a um ou mais caracteres de espaço em branco. Para a maioria das finalidades, essas duas regexes são muito semelhantes, exceto no segundo caso, a regex pode corresponder mais da string, se impedir que a correspondência de regex falhe. de http://www.coderanch.com/t/570917/java/java/regex-difference

evgenyl
fonte
Raspe a palavra "relutantemente". Esta pergunta é sobre \s+, não \s+?como aquela outra pergunta.
Alan Moore