Regex per sostituire più spazi con un singolo spazio


511

Data una stringa come:

"Il cane ha una coda lunga ed è ROSSO!"

Che tipo di magia jQuery o JavaScript può essere utilizzata per mantenere gli spazi al massimo di uno spazio?

Obbiettivo:

"Il cane ha una coda lunga ed è ROSSO!"

4
Vuoi anche abbinare i caratteri della scheda whitespacy?
Chris Farmer,

@ Chris, Sì, per favore, ottima domanda .... Con tutte queste diverse risposte, come si può sapere qual è la soluzione più efficiente?
AnApprentice,

2
Tutti sotto hanno ragione, ma questa è la regex più ottimizzata: str.replace(/ +(?= )/g,'');non stai sostituendo nulla che non devi.
Evan Carroll,

2
Non ci sarà alcuna differenza evidente nelle prestazioni. Potresti sempre profilarlo, ma dubito che ne varrebbe la pena. Vorrei andare per il più chiaro.
Draemon,

@EvanCarroll: non è vero - almeno su Firefox. Quella versione funziona molto più lentamente. Vedi i risultati della profilazione nella mia risposta (sotto).
Edward Loper,

Risposte:


937

Dato che vuoi anche coprire schede, newline, ecc., Sostituisci semplicemente \s\s+con ' ':

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

Se vuoi davvero coprire solo spazi (e quindi non tabulazioni, newline, ecc.), Fallo:

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

4
Devi anche aggiungere il flag 'g' alla regex.
Rafael,

6
Questo non funziona quando è necessario uno spazio vuoto anziché una scheda o una nuova riga. Giusto? / \ s + / funzionerebbe.
Fabian,

3
potrebbe essere meglio per te come una funzione comefunction removeExtraSpaces(string){ return string.replace(/\s{2,}/g, ' ');}
Chiller Math

5
@Ethan: JS ha una funzione built-in che: trim(). È più veloce di regex. Potresti semplicemente fare string.trim().replace(/\s\s+/g, ' ');o string.replace(/\s\s+/g, ' ').trim();.
BalusC

4
/\s\s+/ge /\s{2,}/gnon corrispondono a caratteri spaziosi a meno che non vi siano almeno due adiacenti l'uno all'altro, ad esempio corrisponderanno a \ t \ t ma non corrisponderanno a singoli \ t. string.replace(/\s+/g, ' ')corrisponderà a tutte le sottostringhe di carattere spazioso singolo e multiplo e sostituirà con spazio singolo.
remy Attuale

159

Dal momento che sembra che tu sia interessato alla performance, ho profilato questi con firebug. Ecco i risultati che ho ottenuto:

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

Questo è su Firefox, con sostituzioni di stringa da 100k.

Ti incoraggio a fare i tuoi test di profilazione con firebug, se ritieni che le prestazioni siano un problema. Gli umani sono notoriamente cattivi nel prevedere dove si trovano i colli di bottiglia nei loro programmi.

(Inoltre, tieni presente che la barra degli strumenti per sviluppatori di IE 8 ha anche un profiler incorporato: potrebbe valere la pena verificare come sono le prestazioni in IE.)


5
jsperf.com/removing-multiple-spaces Vai avanti e JSPerf! L'ultimo metodo; ( / +(?= )/g, ' ');fallisce in IE9, lascia doppi spazi: "Foo Bar Baz".replace(/ +(?= )/g, ' ');->"Foo Bar Baz"
Nenotlep

come c'è molta diff bw 1 e 2a riga
Vivek Panday

@VivekPanday - Immagino che ciò sia dovuto al fatto che la seconda riga sostituisce solo le occorrenze di doppi spazi con un singolo spazio, mentre la prima sostituisce anche qualsiasi spazio con uno spazio. Se questo è tempo risparmiato durante la ricerca o la sostituzione effettiva, non lo so.
Maloric

Questo non rimuove gli spazi bianchi iniziali e finali. Per questo vedi questa risposta .
Ethan,

Modificato per ordinare diminuendo la velocità. I commenti di Vivek e Maloric si riferiscono a righe con 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 si desidera sostituire tutti i tipi di caratteri di spazi bianchi, il modo più efficiente sarebbe così:

str = str.replace(/\s{2,}/g,' ');

Divertente la tua stringa di test non ha nemmeno due spazi.
Josh Stodola,

ho appena realizzato che avevi già quello che mi è venuto in mente di recente, +1 :)
meder omuraliev il

2
Per qualche motivo questo non funziona ... Un sacco di "& nbsp;" si stanno presentando ... Probabilmente a causa di CKEDITOR ...
AnApprentice,

K scopre che il testo di JQUERY () stava rovinando le cose. risolto - grazie a tutti!
AnApprentice,

16

Questa è una soluzione, sebbene indirizzerà tutti i caratteri spaziali:

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

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

Modifica : probabilmente è meglio poiché ha come target uno spazio seguito da 1 o più spazi:

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

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

Metodo alternativo:

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

Non ho usato /\s+/da solo poiché questo sostituisce più volte spazi che si estendono su 1 carattere e potrebbe essere meno efficiente poiché bersaglia più del necessario.

Non ho testato a fondo nessuno di questi, quindi se ci sono dei bug.

Inoltre, se hai intenzione di eseguire la sostituzione della stringa, ricorda di riassegnare la variabile / proprietà alla sua sostituzione, ad esempio:

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

Utilizzando jQuery.prototype.text:

var el = $('span:eq(0)');
el.text( el.text().replace(/\d+/, '') )

1
Il primo è totalmente inutile, significa \ s \ s +, un \ s seguito da uno o più \ s +, che può essere ridotto a un singolo \ s +, il secondo esempio è più preciso perché vogliamo solo sostituire i doppi spazi, non Newline, il terzo è più ottimizzato perché si applica solo agli esempi con 2+ spazi. Ma str.replace (/ + (? =) / G, '') ;, si applica solo agli esempi con 2+ spazi ma risparmia sovrascrivendo uno spazio con un passo di spazio.
Evan Carroll,

4
EvanCarroll fallisci perché \ s \ s + è decisamente diverso da \ s +. \ s \ s + corrisponderebbe a '\ t \ t' o '\ t \ t \ t' ma NON '\ t'. Ed è di questo che si tratta, non si desidera sostituire ogni singolo carattere di spazio bianco.
Watain,

Lo voglio. Utilizzato per la ricerca full-text (e visualizzazione snippet): nessuna scheda casuale, non-breaker o cose simili, per favore.
T4NK3R,

13

Ho questo metodo, lo chiamo metodo Derp per mancanza di un nome migliore.

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

Eseguirlo in JSPerf dà alcuni risultati sorprendenti.


2
Sarò imbarazzato da morire se si scopre che ho rovesciato il test case invece che in realtà è veloce: D
Nenotlep

Fornire un test case ... Ottima risposta!
Oytun,

2
Questo ha reso la mia giornata :-) Divertente come "derping" spesso funzioni meglio di essere tutti "intelligenti". La "divisione Derp" sembra aver preso a calci nel culo però. Tuttavia, merita il voto.
Fred Gandt,

13

Un metodo più robusto: si occupa anche di rimuovere gli spazi iniziali e finali, se presenti. Per esempio:

// 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 !"

Il tuo esempio non aveva quegli spazi ma sono anche uno scenario molto comune, e la risposta accettata era solo quella di tagliare quelli in singoli spazi, come: "Il ... ROSSO!", Che non è quello che ti serve in genere.


3
Ho usato questo modello su PHP e funziona. $ parts = preg_split ("/ ^ \ s + | \ s + $ | \ s + (? = \ s) /", "Avenida Tancredo Neves, 745 Piso Térreo Sala");
Bruno Ribeiro,

11

Più robusto:

funzione trim (parola)
{
    word = word.replace (/ [^ \ x21- \ x7E] + / g, ''); // cambia i caratteri non stampabili in spazi
    return word.replace (/ ^ \ s + | \ s + $ / g, ''); // rimuove gli spazi iniziali / finali
}

8

suggerisco

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

solo per spazi
OR

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

per trasformare anche più ritorni in un singolo ritorno.


6

So di essere in ritardo alla festa, ma ho scoperto una bella soluzione.

Ecco qui:

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

6

Ecco una soluzione alternativa se non si desidera utilizzare Sostituisci (sostituire gli spazi in una stringa senza utilizzare Sostituisci javascript)

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);

5

Risposta completa non crittografata per i neofiti et al.

Questo è per tutti i manichini come me che testano gli script scritti da alcuni di voi ragazzi che non funzionano.

I seguenti 3 esempi sono i passaggi che ho seguito per rimuovere caratteri speciali E spazi extra sui seguenti 3 siti Web (che funzionano tutti perfettamente) {1. EtaVisa.com 2. EtaStatus.com 3. Tikun.com} quindi so che funzionano perfettamente.

Li abbiamo incatenati insieme a oltre 50 alla volta e NESSUN problema.

// Questo ha rimosso i caratteri speciali + 0-9 e consente solo lettere (maiuscole e minuscole)

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

// Rimuove i caratteri speciali e consente solo lettere (maiuscole e minuscole) e 0-9 spazi AND

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

// Questo ha rimosso i caratteri speciali e consente solo lettere (maiuscole e minuscole) e 0-9 AND spazi // Il .replace (/ \ s \ s + / g, "") alla fine rimuove gli spazi eccessivi // quando I usato virgolette singole, non ha funzionato.

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

:: SUCCESSIVO :: Salva # 3 come a .js// Ho chiamato il mio NoDoubles.js

:: SUCCESSIVO :: Includi il tuo JS nella tua pagina

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

Includilo nel tuo campo del modulo :: come

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

In modo che assomigli a questo

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

Ciò rimuoverà i caratteri speciali, consentirà spazi singoli e rimuoverà gli spazi extra.


Cosa sta succedendo qui? La formattazione sembra molto, molto rotta.
Nenotlep,

4

Anche una possibilità:

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

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

O se vuoi anche sostituire le schede:

var replaced = string.replace(/\s+/g, " ");

1
usare + sembra più pulito ma sostituirà anche singoli spazi con spazi singoli, un po 'ridondanti e non sono sicuro, ma potrebbe creare problemi di performance con un testo molto più lungo.
ahmetunal,

Tendo a utilizzare la soluzione più breve e più semplice che funzionerà, e mi preoccupo di quel tipo di ottimizzazione se so che devo abbinare una stringa molto grande, a quel punto misurerò effettivamente diverse soluzioni per vedere quale essere più veloce. Può essere difficile prevedere in anticipo quale sarà il più veloce senza test; ad esempio, negli interpreti JavaScript, alcune espressioni regolari complicate ti faranno passare da un'implementazione compilata JIT rapida a una interpretata lentamente.
Brian Campbell,

1

Jquery ha la funzione trim () che fondamentalmente trasforma qualcosa come questa "FOo Bar" in "FOo Bar".

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

È molto più utile perché rimuove automaticamente gli spazi vuoti all'inizio e alla fine della stringa. Nessuna regex necessaria.


3
Come hai detto, trim () rimuove gli spazi vuoti all'inizio e alla fine della stringa, ma non al centro della stringa, quindi, in questo caso non funziona, l'output sarebbe semplicemente "La mia stringa con più Linee". api.jquery.com/jQuery.trim
egvaldes,

1

è sostituito non viene utilizzato, string = string.split (/ \ W + /);


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

str = str.replace(myregexp,' ');

0

Possiamo usare il seguente regex spiegato con l'aiuto del comando di sistema sed. Il regex simile può essere utilizzato in altre lingue e piattaforme.

Aggiungi il testo in un file per dire test

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

Possiamo usare la seguente regex per sostituire tutti gli spazi bianchi con uno spazio singolo

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

Spero che questo serva allo scopo


0

Prova questo per sostituire più spazi con un singolo spazio.

<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>

Leggi di più @ Sostituzione di più spazi con spazio singolo


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

risultato:

"xxx df dfvdfv df dfv"

0

Per un maggiore controllo è possibile utilizzare il callback di sostituzione per gestire il valore.

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"

0

Questo script rimuove qualsiasi spazio bianco (più spazi, tabulazioni, ritorni, ecc.) Tra parole e tagli:

// 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, ' ');
};

0

'mouse pointer touch' .replace (/ ^ \ s + | \ s + $ | (\ s) + / g, "$ 1") dovrebbe fare il trucco!


0

So che dobbiamo usare regex, ma durante un'intervista mi è stato chiesto di fare SENZA USARE REGEX.

@slightlytyler mi ha aiutato a venire con l'approccio di seguito.

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));


considera: console.log (testStr.split ("") .filter (s => s.length) .join (""))
dpjanes
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.