Regex, um mehrere Leerzeichen durch ein einzelnes Leerzeichen zu ersetzen

510

Gegeben eine Zeichenfolge wie:

"Der Hund hat einen langen Schwanz und er ist ROT!"

Welche Art von jQuery- oder JavaScript-Magie kann verwendet werden, um Leerzeichen auf maximal ein Leerzeichen zu beschränken?

Tor:

"Der Hund hat einen langen Schwanz und er ist ROT!"
Ein Lehrling
quelle
4
Möchten Sie auch Whitespacy-Tabulatorzeichen abgleichen?
Chris Farmer
@ Chris, ja bitte, tolle Frage .... Wie soll man bei all diesen unterschiedlichen Antworten wissen, welche die effizienteste Lösung ist?
AnApprentice
2
Alle unten haben Recht, aber dies ist der am besten optimierte reguläre Ausdruck: str.replace(/ +(?= )/g,'');Sie ersetzen nichts, was Sie nicht müssen.
Evan Carroll
2
Es wird keinen merklichen Leistungsunterschied geben. Sie könnten es immer profilieren, aber ich bezweifle, dass es sich lohnt. Ich würde am klarsten gehen.
Draemon
@EvanCarroll: Nicht wahr - zumindest bei Firefox. Diese Version läuft deutlich langsamer. Siehe die Profilerstellungsergebnisse in meiner Antwort (unten).
Edward Loper

Antworten:

937

Vorausgesetzt , dass Sie auch auf Abdecklaschen wollen, Zeilenumbrüche, etc., ersetzen Sie einfach \s\s+mit ' ':

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

Wenn Sie wirklich nur Leerzeichen (und damit keine Tabulatoren, Zeilenumbrüche usw.) abdecken möchten, gehen Sie folgendermaßen vor:

string = string.replace(/  +/g, ' ');
BalusC
quelle
4
Sie müssen dem regulären Ausdruck auch das Flag 'g' hinzufügen.
Rafael
6
Dies funktioniert nicht, wenn ein Leerzeichen anstelle eines Tabulators oder einer neuen Zeile benötigt wird. Recht? / \ s + / würde funktionieren.
Fabian
3
Es wäre vielleicht besser für Sie als Funktion wiefunction removeExtraSpaces(string){ return string.replace(/\s{2,}/g, ' ');}
Math Chiller
5
@Ethan: JS hat eine eingebaute Funktion dafür : trim(). Es ist schneller als Regex. Du könntest es einfach tun string.trim().replace(/\s\s+/g, ' ');oder string.replace(/\s\s+/g, ' ').trim();.
BalusC
4
/\s\s+/gund /\s{2,}/gstimmen nicht mit Leerzeichen überein, es sei denn, es sind mindestens zwei nebeneinander, z. B. stimmt mit \ t \ t überein, stimmt jedoch nicht mit einzelnen \ t überein. string.replace(/\s+/g, ' ')wird mit allen einzelnen und mehreren Leerzeichen-Teilzeichenfolgen übereinstimmen und durch ein einzelnes Leerzeichen ersetzt.
RemyActual
159

Da Sie an Leistung interessiert zu sein scheinen, habe ich diese mit Firebug profiliert. Hier sind die Ergebnisse, die ich erhalten habe:

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

Dies ist in Firefox der Fall, wo 100.000 Zeichenfolgen ersetzt werden.

Ich empfehle Ihnen, Ihre eigenen Profiling-Tests mit Firebug durchzuführen, wenn Sie der Meinung sind, dass die Leistung ein Problem darstellt. Menschen sind notorisch schlecht darin, vorherzusagen, wo die Engpässe in ihren Programmen liegen.

(Beachten Sie außerdem, dass in der Entwickler-Symbolleiste von IE 8 auch ein Profiler integriert ist. Es kann sich lohnen, die Leistung im IE zu überprüfen.)

Edward Loper
quelle
5
jsperf.com/removing-multiple-spaces Gehen Sie weiter und JSPerf! Die letzte Methode; ( / +(?= )/g, ' ');schlägt in IE9 fehl, es "Foo Bar Baz".replace(/ +(?= )/g, ' ');"Foo Bar Baz"
bleiben
wie viel es gibt Unterschied zwischen 1 und 2. Zeile
Vivek Panday
@VivekPanday - Ich stelle mir vor, dass dies daran liegt, dass die zweite Zeile nur das Auftreten von doppelten Leerzeichen durch ein einzelnes Leerzeichen ersetzt, während die erste Zeile jedes Leerzeichen durch ein Leerzeichen ersetzt. Ob dies während der Suche oder beim tatsächlichen Ersetzen Zeit spart, weiß ich nicht.
Maloric
Dadurch werden die anfänglichen und nachfolgenden Leerzeichen nicht entfernt. Siehe dazu diese Antwort .
Ethan
Auf Bestellung durch Verringern der Geschwindigkeit bearbeitet. Die Kommentare von Vivek und Maloric beziehen sich auf Zeilen mit 380 ms und 790 ms.
Skippy le Grand Gourou
43
var str = "The      dog        has a long tail,      and it is RED!";
str = str.replace(/ {2,}/g,' ');

BEARBEITEN: Wenn Sie alle Arten von Leerzeichen ersetzen möchten, wäre der effizienteste Weg wie folgt:

str = str.replace(/\s{2,}/g,' ');
Watain
quelle
Komisch, dass Ihre Testzeichenfolge nicht einmal zwei Leerzeichen enthält.
Josh Stodola
Ich habe gerade festgestellt, dass du bereits das
hattest,
2
Aus irgendeinem Grund funktioniert dies nicht ... Viele "& nbsp;" tauchen auf ... Wahrscheinlich wegen CKEDITOR ...
AnApprentice
K stellt sich heraus, dass JQUERYS Text () die Dinge durcheinander gebracht hat. behoben - danke an alle!
AnApprentice
16

Dies ist eine Lösung, die jedoch auf alle Leerzeichen abzielt:

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

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

Bearbeiten : Dies ist wahrscheinlich besser, da es auf ein Leerzeichen abzielt, gefolgt von einem oder mehreren Leerzeichen:

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

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

Alternative Methode:

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

Ich habe es nicht /\s+/alleine verwendet, da dies Leerzeichen ersetzt, die 1 Zeichen mehrmals umfassen und möglicherweise weniger effizient sind, da es mehr als nötig als Ziel hat.

Ich habe keines davon gründlich getestet, um festzustellen, ob es Fehler gibt.

Wenn Sie Zeichenfolgen ersetzen möchten, müssen Sie die Variable / Eigenschaft auch ihrer eigenen Ersetzung zuweisen, z.

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

Verwenden von jQuery.prototype.text:

var el = $('span:eq(0)');
el.text( el.text().replace(/\d+/, '') )
meder omuraliev
quelle
1
Das erste Beispiel ist völlig sinnlos. \ S \ s + bedeutet, ein \ s gefolgt von einem oder mehreren \ s +, das auf ein einzelnes \ s + reduziert werden kann. Das zweite Beispiel ist genauer, da wir nur doppelte Leerzeichen ersetzen möchten, nicht Zeilenumbrüche, der dritte ist optimierter, da er nur für Beispiele mit 2+ Leerzeichen gilt. Str.replace (/ + (? =) / G, ''); gilt jedoch nur für Beispiele mit 2+ Leerzeichen, spart jedoch das Überschreiben eines Leerzeichens mit einem Leerzeichenschritt.
Evan Carroll
4
EvanCarroll Sie scheitern, weil \ s \ s + definitiv anders ist als \ s +. \ s \ s + würde mit '\ t \ t' oder '\ t \ t \ t' übereinstimmen, aber NICHT mit '\ t'. Und darum geht es, Sie möchten nicht jedes f-en einzelne Leerzeichen ersetzen.
Watain
Ich mache. Wird für die Volltextsuche (und die Snippet-Anzeige) verwendet: Bitte keine zufälligen Tabs, Non-Breaker oder Dingsbums.
T4NK3R
13

Ich habe diese Methode, ich nenne sie die Derp-Methode, weil ich keinen besseren Namen habe.

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

Das Ausführen in JSPerf liefert einige überraschende Ergebnisse.

Nenotlep
quelle
2
Es wird mir höllisch peinlich sein, wenn sich herausstellt, dass ich den Testfall durcheinander gebracht habe, anstatt dass er tatsächlich schnell ist: D
Nenotlep
Bereitstellung eines Testfalls ... Ausgezeichnete Antwort!
Oytun
2
Das machte meinen Tag :-) Lustig, wie "Derping" oft besser funktioniert als "klug" zu sein. Der "Derp Split" scheint ihm allerdings in den Arsch getreten zu haben. Trotzdem verdient eine Abstimmung.
Fred Gandt
13

Eine robustere Methode: Dadurch wird auch sichergestellt, dass auch die anfänglichen und nachfolgenden Leerzeichen entfernt werden, falls vorhanden. Z.B:

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

Ihr Beispiel hatte diese Leerzeichen nicht, aber sie sind auch ein sehr häufiges Szenario, und die akzeptierte Antwort bestand darin, diese nur in einzelne Leerzeichen zu zerlegen, z. B. "The ... RED!", Was normalerweise nicht erforderlich ist.

Ethan
quelle
3
Ich habe dieses Muster auf PHP verwendet und funktioniert. $ parts = preg_split ("/ ^ \ s + | \ s + $ | \ s + (? = \ s) /", "Avenida Tancredo Neves, 745 Piso Térreo Sala");
Bruno Ribeiro
11

Robuster:

Funktionsabgleich (Wort)
{
    word = word.replace (/ [^ \ x21- \ x7E] + / g, ''); // Nicht druckbare Zeichen in Leerzeichen ändern
    return word.replace (/ ^ \ s + | \ s + $ / g, ''); // führende / nachfolgende Leerzeichen entfernen
}}
Chris
quelle
8

Ich schlage vor

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

für nur Leerzeichen
ODER

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

um auch mehrere Retouren in eine einzige zu verwandeln.

Leonard Meagher
quelle
6

Ich weiß, dass ich zu spät zur Party komme, aber ich habe eine schöne Lösung gefunden.

Hier ist es:

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

Hier ist eine alternative Lösung, wenn Sie nicht ersetzen möchten (ersetzen Sie Leerzeichen in einer Zeichenfolge, ohne Javascript zu ersetzen).

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

Umfassende unverschlüsselte Antwort für Neulinge et al.

Dies ist für alle Dummies wie mich, die die Skripte testen, die von einigen von euch geschrieben wurden, die nicht funktionieren.

Die folgenden 3 Beispiele sind die Schritte, die ich unternommen habe, um Sonderzeichen UND zusätzliche Leerzeichen auf den folgenden 3 Websites zu entfernen (die alle perfekt funktionieren) {1. EtaVisa.com 2. EtaStatus.com 3. Tikun.com}, damit ich weiß, dass diese perfekt funktionieren.

Wir haben diese zusammen mit über 50 gleichzeitig und ohne Probleme verkettet.

// Dies entfernte Sonderzeichen + 0-9 und erlaubt nur Buchstaben (Groß- und Kleinschreibung)

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

// Dies entfernt Sonderzeichen und erlaubt nur Buchstaben (Groß- und Kleinschreibung) und 0-9 UND-Leerzeichen

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

// Dies entfernt Sonderzeichen und erlaubt nur Buchstaben (Groß- und Kleinbuchstaben) und 0-9 UND-Leerzeichen // Die .replace (/ \ s \ s + / g, "") am Ende entfernt überschüssige Leerzeichen // wenn ich verwendete einfache Anführungszeichen, es hat nicht funktioniert.

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 :: Speichern Sie # 3 als a .js// Ich habe meine NoDoubles.js aufgerufen

:: NEXT :: Fügen Sie Ihre JS in Ihre Seite ein

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

Fügen Sie dies in Ihr Formularfeld ein :: wie z

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

Damit es so aussieht

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

Dadurch werden Sonderzeichen entfernt, einzelne Leerzeichen zugelassen und zusätzliche Leerzeichen entfernt.

PatFoster
quelle
Was geht hier vor sich? Die Formatierung sieht sehr, sehr kaputt aus.
Nenotlep
4

Auch eine Möglichkeit:

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

Oder wenn Sie auch Registerkarten ersetzen möchten:

var replaced = string.replace(/\s+/g, " ");
Brian Campbell
quelle
1
Die Verwendung von + scheint sauberer zu sein, ersetzt jedoch auch einzelne Leerzeichen durch einzelne Leerzeichen, die etwas überflüssig sind, und ich bin mir nicht sicher, kann jedoch bei einem viel längeren Text zu Leistungsproblemen führen.
ahmetunal
Ich neige dazu, die kürzeste und einfachste Lösung zu verwenden, die funktioniert, und mache mir nur dann Gedanken über diese Art der Optimierung, wenn ich weiß, dass ich mit einer sehr großen Zeichenfolge übereinstimmen muss. An diesem Punkt werde ich tatsächlich verschiedene Lösungen messen, um zu sehen, welche funktionieren sei schneller. Es kann schwierig sein, im Voraus vorherzusagen, was ohne Tests am schnellsten sein wird. In JavaScript-Interpreten führen einige komplizierte reguläre Ausdrücke beispielsweise dazu, dass Sie von einer schnellen JIT-kompilierten Implementierung zu einer langsam interpretierten Implementierung wechseln.
Brian Campbell
1

Jquery hat die Funktion trim (), die so etwas wie diese "FOo Bar" in "FOo Bar" verwandelt.

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

Dies ist viel nützlicher, da Leerzeichen am Anfang und am Ende der Zeichenfolge automatisch entfernt werden. Keine Regex erforderlich.

Eryk Wróbel
quelle
3
Wie Sie sagten, entfernt trim () leere Leerzeichen am Anfang und am Ende der Zeichenfolge, jedoch nicht in der Mitte der Zeichenfolge. In diesem Fall funktioniert dies nicht. Die Ausgabe lautet lediglich "Meine Zeichenfolge mit mehreren Zeichenfolgen" Linien". api.jquery.com/jQuery.trim
egvaldes
1

is replace wird nicht verwendet, string = string.split (/ \ W + /);

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

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

Wir können den folgenden regulären Ausdruck verwenden, der mit Hilfe des Befehls sed system erklärt wurde. Der ähnliche reguläre Ausdruck kann in anderen Sprachen und Plattformen verwendet werden.

Fügen Sie den Text in eine Datei ein, z. B. Test

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

Wir können den folgenden regulären Ausdruck verwenden, um alle Leerzeichen durch einzelne Leerzeichen zu ersetzen

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

Hoffe das dient dem Zweck

minhas23
quelle
0

Versuchen Sie dies, um mehrere Leerzeichen durch ein einzelnes Leerzeichen zu ersetzen.

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

Lesen Sie mehr @ Ersetzen mehrerer Leerzeichen durch ein einzelnes Leerzeichen

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

Ergebnis:

"xxx df dfvdfv df dfv"
Toolkit
quelle
0

Für mehr Kontrolle können Sie den Ersetzungsrückruf verwenden, um den Wert zu verarbeiten.

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

Dieses Skript entfernt Leerzeichen (mehrere Leerzeichen, Tabulatoren, Rückgaben usw.) zwischen Wörtern und Trimms:

// 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
quelle
0

'Mauszeiger berühren' .replace (/ ^ \ s + | \ s + $ | (\ s) + / g, "$ 1") sollte den Trick machen!

Ruwan Epage
quelle
0

Ich weiß, dass wir Regex verwenden müssen, aber während eines Interviews wurde ich gebeten, dies ohne Verwendung von REGEX zu tun.

@slightlytyler hat mir geholfen, mit dem folgenden Ansatz zu kommen.

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
quelle
Betrachten Sie: console.log (testStr.split ("") .filter (s => s.length) .join (""))
dpjanes