JS-Regex zum Aufteilen nach Zeilen


78

Wie teilt man ein langes Stück Text in separate Zeilen auf? Warum gibt diese Zeile1 zweimal zurück?

/^(.*?)$/mg.exec('line1\r\nline2\r\n');

["line1", "line1"]

Ich habe den mehrzeiligen Modifikator aktiviert, um Anfang und Ende von Zeilen zu erstellen ^und $abzugleichen. Ich habe auch den globalen Modifikator aktiviert, um alle Zeilen zu erfassen .

Ich möchte einen Regex-Split verwenden und nicht, String.splitweil ich mich sowohl mit Linux- \nals auch mit Windows- \r\nZeilenenden befassen werde .

Antworten:


146
arrayOfLines = lineString.match(/[^\r\n]+/g);

Wie Tim sagte, ist es sowohl das gesamte Match als auch das Capture. Es wird angezeigt regex.exec(string), dass die erste Übereinstimmung unabhängig vom globalen Modifikator gefunden string.match(regex)wird, wobei global berücksichtigt wird.


9
Als Hinweis wird Tims mit leeren Zeilen übereinstimmen, während meine nicht. Entweder kann oder kann nicht wünschenswert sein.
ReactiveRaven

Alte Antwort, aber ich möchte sagen, dass der Grund für die execRückkehr bei der ersten Übereinstimmung darin besteht, dass sie für globale Regexe mehrmals aufgerufen werden soll, bis sie null zurückgibt, und die Regex Dinge wie lastIndexden Index speichert, bei dem die nächste beginnen soll Spiel.
iPherian

Versuchen Sie es "123\n\n1234".match(/[^\r\n]+/g);erwartet Array [ "123", "", "1234" ], aber Sie habenArray [ "123", "1234" ]
Seek kg

105

Verwenden

result = subject.split(/\r?\n/);

Ihre Regex wird line1zweimal zurückgegeben, da line1sowohl die gesamte Übereinstimmung als auch der Inhalt der ersten Erfassungsgruppe angezeigt werden.


4
Sie müssen die gFlagge verwenden und \rist auf einigen alten Apple-Maschinen eine gültige neue Zeile. Auch Unicode definiert \u2028, \u2029und die alte IBM Newline \u0085als Zeilenumbrüche. So /[\n\u0085\u2028\u2029]|\r\n?/gkümmert sich um alle Grenzfälle.
Mike Samuel

7
@ Mike: Bist du dir über die /gFlagge sicher ? Es ist nicht sinnvoll, eine Teilungsfunktion zu haben, die nur einmal geteilt wird, sofern nicht ausdrücklich anders angegeben. Und Jojo sagte, dass er nur mit Linux und Windows zu tun hat. Was kommt als nächstes, EBCDIC?
Tim Pietzcker

4
@ Mike: Nein, die /gFlagge ist nicht erforderlich. Sie können es hinzufügen, aber JavaScript ignoriert es einfach. Wie Tim sagte, besteht das Standardverhalten darin, so oft wie möglich zu teilen, aber Sie können das zweite Argument verwenden, um ein Maximum festzulegen.
Alan Moore

23
Was eine Newline ausmacht, ist noch schlimmer. Laut dem Unicode-Konsortium sollten wir immer verwenden (\r\n|[\n\v\f\r\x85\u2028\u2029]), egal auf welcher Plattform die Software ausgeführt wird oder woher die Daten stammen.
Alan Moore

@ Alan, ganz richtig. Das gFlag steuert, ob Erfassungsgruppen in der Ausgabe enthalten sind.
Mike Samuel

26

Ich gehe davon aus, dass das Folgende Zeilenumbrüche darstellt

  1. \ r gefolgt von \ n
  2. \ n gefolgt von \ r
  3. \ n allein anwesend
  4. Ich bin allein anwesend

Bitte verwende

var re=/\r\n|\n\r|\n|\r/g;

arrayofLines=lineString.replace(re,"\n").split("\n");

für ein Array aller Zeilen einschließlich der leeren.

ODER

Bitte verwende

arrayOfLines = lineString.match(/[^\r\n]+/g); 

Für ein Array nicht leerer Zeilen


\ngefolgt von \rist kein einziger Zeilenumbruch
JLRishe

22

Noch einfacher Regex, der alle Zeilenendkombinationen verarbeitet, auch in derselben Datei gemischt, und auch leere Zeilen entfernt:

var lines = text.split(/[\r\n]+/g);

Mit Leerzeichen:

var lines = text.trim().split(/\s*[\r\n]+\s*/g);


1
Der erste entfernt leere Zeilen in der Mitte des Textes, jedoch nicht am Anfang oder am Ende. Das ist in Ordnung für meine Zwecke, ich möchte nur darauf hinweisen, dass jeder, der die Entfernung benötigt, konsistent ist.
Twm

6

Ersetzen Sie zuerst alle \r\ndurch \n, dann String.split .


Dies erfordert zwei Befehle. Kann es mit Regex in einem Befehl gemacht werden?
JoJo

2
@ JoJo: myString.replace(/\r\n/, "\n").split("\n")(es sei denn, Sie fragen wegen akademischen Interesses :))
Tim

'line1\r\nline2\r\n'.replace(/\r\n/, '\n').split('\n').without('');erzeugt eine falsche zweite Zelle:["line1", "line2\r"]
JoJo

@ JoJo: Entschuldigung, ich habe die /gFlagge für global vergessen ! Es sollte sein:myString.replace(/\r\n/g, "\n").split("\n")
Tim

3
@ Jojo: Dies ist kurz und bündig in einer Zeile :) Regexes sind nicht das Werkzeug für jeden Job. Sie können sehr mächtig sein, sollten aber nicht überall eingesetzt werden. Beachten Sie, dass replace ist ein regulärer Ausdruck.
Tim

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.