Jak w węźle podzielić ciąg znaków przez znak nowej linii ('\ n')?

141

Jak w węźle podzielić ciąg znaków przez znak nowej linii ('\ n')? Mam prosty ciąg jak var a = "test.js\nagain.js"i muszę dostać ["test.js", "again.js"]. próbowałem

a.split("\n");
a.split("\\n");
a.split("\r\n");
a.split("\r");

ale żadne z powyższych nie działa.

PaolaJ.
źródło
7
split()nie modyfikuje oryginalnego ciągu.
thgaskell
Wygląda na to, że jest to czyste pytanie JavaScript, niewymagające tagu node.js.
Wyck
@Wyck, warto wiedzieć, że Node jest docelowym środowiskiem wykonawczym, ponieważ newlineznak w ciągu jest często zależny od platformy. W Node.js bardzo często operuje się tekstami plików ze newlineznakami i ważne jest, aby znać platformę. W kontekście przeglądarki to mniejszy problem. Ale sugerowałbym OP zmienić pytanie, aby określić środowisko docelowe, lub poprosić o rozwiązania, które działają ogólnie na wszystkich głównych platformach.
Austin Davis

Odpowiedzi:

256

Spróbuj podzielić na wyrażenie regularne, /\r?\n/które będzie używane zarówno w systemach Windows, jak i UNIX.

> "a\nb\r\nc".split(/\r?\n/)
[ 'a', 'b', 'c' ]
maerics
źródło
3
A co z klasycznymi komputerami Mac? ;)
AshleyF
10
klasyczne Macs zginęły wraz ze Stevem Jobsem ... smutek :(
ymz
46
złapać \ n, \ r i \ r \ n:split(/[\r\n]+/)
Julian TF,
2
MacOSX nie używa już singli, było to tylko dla starych komputerów Mac. Myślę, że mają to samo \ n co inne uniksy.
jcubic
14
/ [\ r \ n] + / odfiltruje puste wiersze
Spongman,
49

Jeśli plik jest natywny dla twojego systemu (z pewnością nie ma takiej gwarancji), Node może ci pomóc:

var os = require('os');

a.split(os.EOL);

Jest to jednak zwykle bardziej przydatne do konstruowania ciągów wyjściowych z Node, ze względu na przenośność platformy.

kubit
źródło
5
Tak, generalnie nie powinieneś tego robić. Powinieneś analizować znaki nowej linii niezależnie od platformy.
1j01
Podkreślam, że dotyczy to szczególnie plików natywnych dla twojego systemu w pierwszym zdaniu. Powyższa odpowiedź jest odpowiednia, gdy jest to nieznane lub mieszane.
qubyte
Dobrze. Lub kiedy jest „znane” teraz, ale może się zmienić w przyszłości.
1j01
działa tylko podczas ładowania plików na platformę, na której zostały utworzone.
Spongman
34

Wygląda na to, że regex /\r\n|\r|\n/obsługuje zakończenia linii CR, LF i CRLF, ich mieszane sekwencje i zachowuje wszystkie puste wiersze pomiędzy nimi. Spróbuj tego!

function splitLines(t) { return t.split(/\r\n|\r|\n/); }

// single newlines
splitLines("AAA\rBBB\nCCC\r\nDDD");
// double newlines
splitLines("EEE\r\rFFF\n\nGGG\r\n\r\nHHH");
// mixed sequences
splitLines("III\n\r\nJJJ\r\r\nKKK\r\n\nLLL\r\n\rMMM");

W rezultacie powinieneś otrzymać te tablice:

[ "AAA", "BBB", "CCC", "DDD" ]
[ "EEE", "", "FFF", "", "GGG", "", "HHH" ]
[ "III", "", "JJJ", "", "KKK", "", "LLL", "", "MMM" ]

Możesz również nauczyć to wyrażenie regularne rozpoznawania innych legalnych terminatorów linii Unicode , dodając |\xHHlub |\uHHHHczęści, gdzie Hsą szesnastkowe cyfry dodatkowego punktu kodowego znaku terminatora (jak widać w artykule w Wikipedii jako U+HHHH).

blakkwater
źródło
31
a = a.split("\n");

Zauważ, że splitting zwraca nową tablicę, zamiast przypisywać ją do oryginalnego ciągu. Musisz jawnie przechowywać to w zmiennej.

Alex
źródło
17

Rozwiązanie, które działa ze wszystkimi możliwymi zakończeniami linii, w tym mieszanymi, a także z zachowaniem pustych linii, można uzyskać za pomocą dwóch zamienników i jednego podziału w następujący sposób

text.replace(/\r\n/g, "\r").replace(/\n/g, "\r").split(/\r/);

jakiś kod do przetestowania

  var CR = "\x0D";  //   \r
  var LF = "\x0A";  //   \n

  var mixedfile = "00" + CR + LF +            // 1 x win
                  "01" + LF +                 // 1 x linux
                  "02" + CR +                 // 1 x old mac
                  "03" + CR + CR +            // 2 x old mac
                  "05" + LF + LF +            // 2 x linux
                  "07" + CR + LF + CR + LF +  // 2 x win
                  "09";

  function showarr (desc, arr)
  {
     console.log ("// ----- " + desc);
     for (var ii in arr)
        console.log (ii + ") [" + arr[ii] +  "] (len = " + arr[ii].length + ")");
  }

  showarr ("using 2 replace + 1 split", 
           mixedfile.replace(/\r\n/g, "\r").replace(/\n/g, "\r").split(/\r/));

i wyjście

  // ----- using 2 replace + 1 split
  0) [00] (len = 2)
  1) [01] (len = 2)
  2) [02] (len = 2)
  3) [03] (len = 2)
  4) [] (len = 0)
  5) [05] (len = 2)
  6) [] (len = 0)
  7) [07] (len = 2)
  8) [] (len = 0)
  9) [09] (len = 2)
Alejadro Xalabarder
źródło
1
Właściwie rozwiązanie podane przez blakkwater: text.split (/ \ r \ n | \ n | \ r /); zrób to samo, a jest krócej i szybciej
Alejadro Xalabarder
8

Pierwsza powinna działać:

> "a\nb".split("\n");
[ 'a', 'b' ]
> var a = "test.js\nagain.js"
undefined
> a.split("\n");
[ 'test.js', 'again.js' ]
TimWolla
źródło
4

Zrobiłem eolmoduł do pracy z zakończeniami linii w węźle lub przeglądarkach. Ma metodę podziału, taką jak

var lines = eol.split(text)
ryanve
źródło