Regex para substituir vários espaços por um único espaço

511

Dada uma string como:

"O cachorro tem uma cauda longa e é VERMELHO!"

Que tipo de magia jQuery ou JavaScript pode ser usada para manter os espaços com apenas um espaço no máximo?

Objetivo:

"O cachorro tem uma cauda longa e é VERMELHO!"
Um aprendiz
fonte
4
Você também deseja combinar caracteres de tabulação de espaços em branco?
Chris Farmer
@ Chris, Sim, por favor, ótima pergunta .... Com todas essas respostas diferentes, como se deve saber qual é a solução mais eficiente?
AnApprentice
2
Todos abaixo estão certos, mas este é o regex mais otimizado: str.replace(/ +(?= )/g,'');você não está substituindo nada que não seja necessário.
Evan Carroll
2
Não haverá nenhuma diferença perceptível no desempenho. Você sempre pode criar um perfil, mas duvido que valha a pena. Eu iria para o mais claro.
30909 Draemon
@EvanCarroll: Não é verdade - pelo menos no Firefox. Essa versão é significativamente mais lenta. Veja os resultados da criação de perfil na minha resposta (abaixo).
Edward Loper

Respostas:

937

Como você também deseja abas, novas linhas etc., substitua \s\s+por ' ':

string = string.replace(/\s\s+/g, ' ');

Se você realmente deseja cobrir apenas espaços (e, portanto, não guias, novas linhas etc.), faça o seguinte:

string = string.replace(/  +/g, ' ');
BalusC
fonte
4
Você também precisa adicionar o sinalizador 'g' ao regex.
1055 Rafael Rafael
6
Isso não está funcionando quando é necessário um espaço em branco em vez de uma guia ou nova linha. Direita? / \ s + / estaria funcionando.
Fabian
3
seria poderia ser melhor para você como uma função, comofunction removeExtraSpaces(string){ return string.replace(/\s{2,}/g, ' ');}
Math chiller
5
@Ethan: JS tem uma função interna para que: trim(). É mais rápido que o regex. Você poderia apenas fazer string.trim().replace(/\s\s+/g, ' ');ou string.replace(/\s\s+/g, ' ').trim();.
precisa saber é o seguinte
4
/\s\s+/ge /\s{2,}/gnão correspondem a caracteres de espaço em branco, a menos que haja pelo menos dois adjacentes um ao outro, por exemplo, corresponderá a \ t \ t, mas não corresponderá a um único \ t. string.replace(/\s+/g, ' ')corresponderá a todas as seqüências de caracteres de espaço em branco único e múltiplo e será substituído por espaço único.
precisa saber é o seguinte
159

Desde que você parece estar interessado em desempenho, eu criei o perfil deles com o firebug. Aqui estão os resultados que obtive:

str.replace( /  +/g, ' ' )       ->  380ms
str.replace( /\s\s+/g, ' ' )     ->  390ms
str.replace( / {2,}/g, ' ' )     ->  470ms
str.replace( / +/g, ' ' )        ->  790ms
str.replace( / +(?= )/g, ' ')    -> 3250ms

Isso está no Firefox, executando 100k substituições de string.

Convido você a fazer seus próprios testes de criação de perfil com o firebug, se você acha que o desempenho é um problema. Os seres humanos são notoriamente ruins em prever onde estão os gargalos em seus programas.

(Observe também que a barra de ferramentas do desenvolvedor do IE 8 também possui um criador de perfil - pode valer a pena verificar como é o desempenho no IE.)

Edward Loper
fonte
5
jsperf.com/removing-multiple-spaces Vá em frente e JSPerf! O último método; ( / +(?= )/g, ' ');falha no IE9, deixa espaços duplos: "Foo Bar Baz".replace(/ +(?= )/g, ' ');->"Foo Bar Baz"
Nenotlep
como há muito bw diff 1 e 2ª linha
Vivek Panday
@VivekPanday - Eu imagino que isso ocorre porque a segunda linha está substituindo apenas ocorrências de espaços duplos por um único espaço, enquanto a primeira está substituindo qualquer espaço por um espaço também. Se esse é o tempo economizado durante a pesquisa ou a substituição real, eu não sei.
Maloric 16/08/19
Isso não remove os espaços em branco iniciais e finais. Para isso veja esta resposta .
Ethan
Editado por ordem, diminuindo a velocidade. Os comentários de Vivek e Maloric referem-se a linhas com 380 ms e 790 ms.
Skippy le Grand Gourou
43
var str = "The      dog        has a long tail,      and it is RED!";
str = str.replace(/ {2,}/g,' ');

EDIT: Se você deseja substituir todos os tipos de caracteres de espaço em branco, a maneira mais eficiente seria a seguinte:

str = str.replace(/\s{2,}/g,' ');
watain
fonte
Engraçado que a sua coluna de teste não tem nem dois espaços.
21139 Josh Stodola
só percebi que já tinha o que eu recentemente veio com, +1 :)
meder omuraliev
2
Por alguma razão, isso não está funcionando ... Muitos "& nbsp;" estão aparecendo ... provavelmente devido a ckeditor ...
AnApprentice
K descobriu que o texto de JQUERY () estava bagunçando as coisas. fixo - obrigado a todos!
AnApprentice
16

Esta é uma solução, embora tenha como alvo todos os caracteres de espaço:

"The      dog        has a long tail,      and it is RED!".replace(/\s\s+/g, ' ')

"The dog has a long tail, and it is RED!"

Editar : provavelmente é melhor, pois tem como alvo um espaço seguido por 1 ou mais espaços:

"The      dog        has a long tail,      and it is RED!".replace(/  +/g, ' ')

"The dog has a long tail, and it is RED!"

Método alternativo:

"The      dog        has a long tail,      and it is RED!".replace(/ {2,}/g, ' ')
"The dog has a long tail, and it is RED!"

Não usei /\s+/por si só, uma vez que substitui espaços que abrangem 1 caractere várias vezes e pode ser menos eficiente, pois tem como alvo mais do que o necessário.

Eu não testei profundamente nenhum deles, então lmk se houver erros.

Além disso, se você for fazer uma substituição de cadeia, lembre-se de atribuir novamente a variável / propriedade à sua própria substituição, por exemplo:

var string = 'foo'
string = string.replace('foo', '')

Usando jQuery.prototype.text:

var el = $('span:eq(0)');
el.text( el.text().replace(/\d+/, '') )
meder omuraliev
fonte
1
O primeiro é totalmente inútil, \ s \ s + significa, an \ s seguido por um ou mais \ s +, que pode ser reduzido a um único \ s +, o segundo exemplo é mais preciso, porque queremos apenas substituir espaços duplos, não novas linhas, a terceira é mais otimizada porque se aplica apenas a exemplos com mais de 2 espaços. Mas str.replace (/ + (? =) / G, '') ;, aplica-se apenas a exemplos com mais de 2 espaços, mas salva a substituição de um espaço com uma etapa de espaço.
Evan Carroll
4
EvanCarroll você falha porque \ s \ s + é definitivamente diferente de \ s +. \ s \ s + corresponderia a '\ t \ t' ou '\ t \ t \ t', mas NÃO '\ t'. E é disso que se trata: você não deseja substituir todos os caracteres de espaço em branco f-en.
Watain
Eu faço. Utilizado para pesquisa de texto completo (e exibição de trechos): sem guias aleatórias, separadores ou objetos de coisas, por favor.
T4NK3R
13

Eu tenho esse método, eu chamo de método Derp por falta de um nome melhor.

while (str.indexOf("  ") !== -1) {
    str = str.replace(/  /g, " ");
}

A execução no JSPerf fornece alguns resultados surpreendentes.

Nenotlep
fonte
2
Vou estar envergonhado como o inferno se ele sair eu falsificado o caso de teste em vez de ele realmente ser rápido: D
Nenotlep
Fornecendo um caso de teste ... Excelente resposta!
Oytun
2
Isso fez o meu dia :-) Engraçado como "derping" geralmente funciona melhor do que ser "inteligente". A "divisão Derp" parece ter chutado sua bunda. Ainda assim, merece votação.
Fred Gandt 07/04
13

Um método mais robusto: isso também remove os espaços iniciais e finais, se existirem. Por exemplo:

// NOTE the possible initial and trailing spaces
var str = "  The dog      has a long   tail, and it     is RED!  "

str = str.replace(/^\s+|\s+$|\s+(?=\s)/g, "");

// str -> "The dog has a long tail, and it is RED !"

Seu exemplo não tinha esses espaços, mas eles também são um cenário muito comum, e a resposta aceita foi apenas recortá-los em espaços únicos, como: "O ... VERMELHO!", Que não é o que você normalmente precisará.

Ethan
fonte
3
Eu usei esse padrão no PHP e funciona. $ parts = preg_split ("/ ^ \ s + | \ s + $ | \ s + (? = \ s) /", "Avenida Tancredo Neves, 745 Piso Térreo Sala");
Bruno Ribeiro
11

Mais robusto:

função trim (word)
{
    word = word.replace (/ [^ \ x21- \ x7E] + / g, ''); // altera caracteres não imprimíveis para espaços
    retornar word.replace (/ ^ \ s + | \ s + $ / g, ''); // remover espaços iniciais / finais
}
Chris
fonte
8

Eu sugiro

string = string.replace(/ +/g," ");

apenas para espaços
OU

string = string.replace(/(\s)+/g,"$1");

por transformar vários retornos em um único retorno também.

Leonard Meagher
fonte
6

Sei que estou atrasado para a festa, mas descobri uma boa solução.

Aqui está:

var myStr = myStr.replace(/[ ][ ]*/g, ' ');
ToXic73
fonte
6

Aqui está uma solução alternativa, se você não quiser usar replace (substitua espaços em uma string sem usar o javascript replace)

var str="The dog      has a long   tail, and it     is RED!";
var rule=/\s{1,}/g;
str = str.split(rule).join(" "); 
document.write(str);
imos
fonte
5

Resposta não criptografada abrangente para iniciantes et al.

Isso é para todos os manequins como eu que testam os scripts escritos por alguns de vocês que não funcionam.

Os três exemplos a seguir são as etapas que eu segui para remover caracteres especiais E espaços extras nos três sites a seguir (todos funcionando perfeitamente) {1. EtaVisa.com 2. EtaStatus.com 3. Tikun.com}, então eu sei que elas funcionam perfeitamente.

Nós os encadeamos com mais de 50 por vez e sem problemas.

// Isso removeu caracteres especiais + 0-9 e permite apenas letras (maiúsculas e minúsculas)

function NoDoublesPls1()
{
var str=document.getElementById("NoDoubles1");
var regex=/[^a-z]/gi;
str.value=str.value.replace(regex ,"");
}

// Isso remove caracteres especiais e permite apenas letras (maiúsculas e minúsculas) e espaços 0-9 AND

function NoDoublesPls2()
{
var str=document.getElementById("NoDoubles2");
var regex=/[^a-z 0-9]/gi;
str.value=str.value.replace(regex ,"");
}

// Isso remove caracteres especiais e permite apenas letras (maiúsculas e minúsculas) e espaços 0-9 AND // O .replace (/ \ s \ s + / g, "") no final remove espaços excessivos // quando eu usou aspas simples, não funcionou.

function NoDoublesPls3()
{    var str=document.getElementById("NoDoubles3");
var regex=/[^a-z 0-9]/gi;
str.value=str.value.replace(regex ,"") .replace(/\s\s+/g, " ");
}

:: NEXT :: Salve # 3 como a .js// eu chamei de NoDoubles.js

:: NEXT :: Inclua seu JS em sua página

 <script language="JavaScript" src="js/NoDoubles.js"></script>

Inclua isso no campo do formulário :: such as

<INPUT type="text" name="Name"
     onKeyUp="NoDoublesPls3()" onKeyDown="NoDoublesPls3()" id="NoDoubles3"/>

Para que fique assim

<INPUT type="text" name="Name" onKeyUp="NoDoublesPls3()" onKeyDown="NoDoublesPls3()" id="NoDoubles3"/>

Isso removerá caracteres especiais, permitirá espaços únicos e removerá espaços extras.

PatFoster
fonte
O que está acontecendo aqui? A formatação parece muito, muito quebrada.
Nenotlep
4

Também uma possibilidade:

str.replace( /\s+/g, ' ' )
rfunduk
fonte
1
var string = "The dog      has a long   tail, and it     is RED!";
var replaced = string.replace(/ +/g, " ");

Ou se você também deseja substituir as guias:

var replaced = string.replace(/\s+/g, " ");
Brian Campbell
fonte
1
usar + parece mais limpo, mas também substituirá espaços únicos por espaços únicos, um pouco redundante e não tenho certeza, mas isso pode criar problemas de desempenho com um texto muito mais longo.
22915 ahmetunal
Costumo usar a solução mais curta e simples que funcionará, e só me preocupo com esse tipo de otimização se souber que preciso fazer uma correspondência com uma string muito grande; nesse momento, na verdade, medirei diferentes soluções para ver qual será seja mais rápido. Pode ser difícil prever com antecedência o que será mais rápido sem teste; por exemplo, em intérpretes JavaScript, algumas expressões regulares complicadas farão com que você mude de uma implementação compilada JIT rápida para uma implementação lenta interpretada.
Brian Campbell
1

Jquery possui a função trim () que basicamente transforma algo como "FOo Bar" em "FOo Bar".

var string = "  My     String with  Multiple lines    ";
string.trim(); // output "My String with Multiple lines"

É muito mais útil, pois remove automaticamente os espaços vazios no início e no final da string. Não é necessário regex.

Eryk Wróbel
fonte
3
Como você disse, trim () remove espaços vazios no início e no final da string, mas não no meio da string, portanto, não funciona nesse caso, a saída seria apenas "My String with Multiple linhas ". api.jquery.com/jQuery.trim
egvaldes
1

é substituir não é usado, string = string.split (/ \ W + /);

Lin
fonte
0
var myregexp = new RegExp(/ {2,}/g);

str = str.replace(myregexp,' ');
ahmetunal
fonte
0

Podemos usar o seguinte regex explicado com a ajuda do comando sed system. O regex semelhante pode ser usado em outros idiomas e plataformas.

Adicione o texto em algum arquivo, digamos test

manjeet-laptop:Desktop manjeet$ cat test
"The dog      has a long   tail, and it     is RED!"

Podemos usar o seguinte regex para substituir todos os espaços em branco por um único espaço

manjeet-laptop:Desktop manjeet$ sed 's/ \{1,\}/ /g' test
"The dog has a long tail, and it is RED!"

Espero que isso sirva ao propósito

minhas23
fonte
0

Tente isso para substituir vários espaços por um único espaço.

<script type="text/javascript">
    var myStr = "The dog      has a long   tail, and it     is RED!";
    alert(myStr);  // Output 'The dog      has a long   tail, and it     is RED!'

    var newStr = myStr.replace(/  +/g, ' ');
    alert(newStr);  // Output 'The dog has a long tail, and it is RED!'
</script>

Leia mais @ Substituindo vários espaços por espaço único

jonathan klevin
fonte
0
var text = `xxx  df dfvdfv  df    
                     dfv`.split(/[\s,\t,\r,\n]+/).filter(x=>x).join(' ');

resultado:

"xxx df dfvdfv df dfv"
Conjunto de ferramentas
fonte
0

Para obter mais controle, você pode usar o retorno de chamada de substituição para manipular o valor.

value = "tags:HUNT  tags:HUNT         tags:HUNT  tags:HUNT"
value.replace(new RegExp(`(?:\\s+)(?:tags)`, 'g'), $1 => ` ${$1.trim()}`)
//"tags:HUNT tags:HUNT tags:HUNT tags:HUNT"
jackotonye
fonte
0

Esse script remove qualquer espaço em branco (vários espaços, guias, retornos etc.) entre palavras e acabamentos:

// Trims & replaces any wihtespacing to single space between words
String.prototype.clearExtraSpace = function(){
  var _trimLeft  = /^\s+/,
      _trimRight = /\s+$/,
      _multiple  = /\s+/g;

  return this.replace(_trimLeft, '').replace(_trimRight, '').replace(_multiple, ' ');
};
Oriol
fonte
0

'toque do ponteiro do mouse' .replace (/ ^ \ s + | \ s + $ | (\ s) + / g, "$ 1") deve fazer o truque!

Ruwan Epage
fonte
0

Sei que precisamos usar regex, mas durante uma entrevista, fui solicitado a fazer SEM USAR REGEX.

@slightlytyler me ajudou a seguir a abordagem abaixo.

const testStr = "I   LOVE    STACKOVERFLOW   LOL";

const removeSpaces = str  => {
  const chars = str.split('');
  const nextChars = chars.reduce(
    (acc, c) => {
      if (c === ' ') {
        const lastChar = acc[acc.length - 1];
        if (lastChar === ' ') {
          return acc;
        }
      }
      return [...acc, c];
    },
    [],
  );
  const nextStr = nextChars.join('');
  return nextStr
};

console.log(removeSpaces(testStr));

xSachinx
fonte
considere: console.log (testStr.split ("") .filter (s => s.length) .join ("")))
dpjanes em 28/03