Existe uma diferença entre / \ s / ge / \ s + / g?

87

Quando temos uma string que contém caracteres de espaço:

var str = '  A B  C   D EF ';

e queremos remover os espaços da string (queremos isso 'ABCDEF':).

Ambos:

str.replace(/\s/g, '')

e isto:

str.replace(/\s+/g, '')

retornará o resultado correto.

Isso significa que o +é supérfluo nessa situação? Há uma diferença entre essas duas expressões regulares nesta situação (como em, elas poderiam de alguma forma produzir resultados diferentes)?


Atualização: comparação de desempenho - /\s+/gé mais rápido. Veja aqui: http://jsperf.com/s-vs-s

Šime Vidas
fonte
1
vidas stackoverflow.com/questions/5963182/… Aposto que foi isso que fez você fazer essa pergunta;) (seu comentário sobre a resposta)
rsplak
2
Posso imaginar que \s+é mais rápido, porque pode substituir pedaços de espaço em branco, enquanto \sdeve substituir cada espaço em branco separadamente?
KooiInc
1
@KooiInc: Correto, porque corresponde / substitui menos vezes.
BoltClock

Respostas:

214

Na primeira regex, cada caractere de espaço está sendo substituído, caractere por caractere, pela string vazia.

Na segunda regex, cada string contígua de caracteres de espaço está sendo substituída pela string vazia devido ao +.

No entanto, assim como 0 multiplicado por qualquer outra coisa é 0, parece que os dois métodos retiram os espaços exatamente da mesma maneira.

Se você alterar a string de substituição para '#', a diferença se torna muito mais clara:

var str = '  A B  C   D EF ';
console.log(str.replace(/\s/g, '#'));  // ##A#B##C###D#EF#
console.log(str.replace(/\s+/g, '#')); // #A#B#C#D#EF#
BoltClock
fonte
27

\ssignifica "um espaço" e \s+significa "um ou mais espaços".

Mas, como você está usando o /gsinalizador (substitua todas as ocorrências) e substituindo pela string vazia, suas duas expressões têm o mesmo efeito.

Lightness Races in Orbit
fonte
Mas a segunda versão provavelmente será mais rápida.
Tim Pietzcker
isso significa que não preciso usar / g se estiver usando \ s +
Gaurav
1
@Gaurav: Não. Porque então substituiria apenas o primeiro \s+, deixando o resto intacto. Por exemplo, ' foo bar '.replace(/\s+/, '')daria a você apenas 'foo bar ' editar argh HTML condensando dois espaços em um
BoltClock
@Gaurav Acho que não. Se você omitir o gmodificador, apenas a primeira ocorrência de um bloco de espaços em branco será substituída.
KooiInc
10

Em uma situação de correspondência, o primeiro retornaria uma correspondência por espaço em branco, enquanto o segundo retornaria uma correspondência para cada grupo de espaços em branco.

O resultado é o mesmo porque você o está substituindo por uma string vazia. Se você substituí-lo por 'x', por exemplo, os resultados seriam diferentes.

str.replace(/\s/g, '') retornará 'xxAxBxxCxxxDxEF'

while str.replace(/\s+/g, '')retornará 'xAxBxCxDxEF'

porque \scorresponde a cada espaço em branco, substituindo cada um por 'x', e \s+corresponde a grupos de espaços em branco, substituindo vários espaços em branco sequenciais por um único 'x'.

Doug
fonte
3

+significa "um ou mais caracteres" e sem o mais significa "um caractere". No seu caso, ambos resultam na mesma saída.

Josh M.
fonte