¿Cómo en el nodo dividir la cadena por nueva línea ('\ n')?

135

¿Cómo en el nodo dividir la cadena por nueva línea ('\ n')? Tengo una cadena simple como var a = "test.js\nagain.js"y necesito obtener ["test.js", "again.js"]. Lo intenté

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

pero ninguno de los anteriores no funciona.

PaolaJ.
fuente
posible duplicado del carácter de nueva línea de cadena
Mene
77
split()no modifica la cadena original.
thgaskell
Esto parece una pregunta pura de JavaScript, que no requiere una etiqueta node.js.
Wyck

Respuestas:

238

Intenta dividir en una expresión regular como /\r?\n/para ser utilizable por los sistemas Windows y UNIX.

> "a\nb\r\nc".split(/\r?\n/)
[ 'a', 'b', 'c' ]
maerics
fuente
3
¿Qué pasa con los Macs clásicos? ;)
AshleyF
10
Macs clásico murió junto con Steve Jobs ... tristeza :(
ymz
43
para atrapar \ n, \ r y \ r \ n:split(/[\r\n]+/)
Julian TF
2
MacOSX ya no usa single \ r, eso fue solo para Macs viejos. Creo que tienen el mismo \ n que otros unixes.
jcubic
12
/ [\ r \ n] + / filtrará las líneas vacías
Spongman el
49

Si el archivo es nativo de su sistema (ciertamente no hay garantías de eso), entonces Node puede ayudarlo:

var os = require('os');

a.split(os.EOL);

Sin embargo, esto suele ser más útil para construir cadenas de salida desde Node, para la portabilidad de la plataforma.

qubyte
fuente
55
Sí, generalmente no deberías hacer esto. Debe analizar nuevas líneas independientemente de la plataforma.
1j01
Destaco que esto es específicamente para el caso de los archivos nativos de su sistema en la primera oración. La respuesta anterior es apropiada para cuando esto es desconocido o mixto.
qubyte
Correcto. O cuando es "conocido" ahora pero podría cambiar en el futuro.
1j01
solo funciona al cargar archivos en la plataforma en la que se crearon.
Spongman
33

Parece que regex /\r\n|\r|\n/maneja las terminaciones de línea CR, LF y CRLF, sus secuencias mixtas, y mantiene todas las líneas vacías en el medio. ¡Trata eso!

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

Debería obtener estos arreglos como resultado:

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

También puede enseñarle a esa expresión regular a reconocer otros terminadores de línea Unicode legítimos agregando |\xHHo |\uHHHHpartes, donde Hestán los dígitos hexadecimales del punto de código adicional del carácter del terminador (como se ve en el artículo de Wikipedia como U+HHHH).

blakkwater
fuente
30
a = a.split("\n");

Tenga en cuenta que splitting devuelve la nueva matriz, en lugar de solo asignarla a la cadena original. Necesita almacenarlo explícitamente en una variable.

alex
fuente
17

Se puede lograr una solución que funcione con todas las terminaciones de línea posibles, incluidas las mixtas y mantener las líneas vacías utilizando dos reemplazos y una división de la siguiente manera

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

algún código para probarlo

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

y la salida

  // ----- 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
fuente
1
En realidad, la solución dada por blakkwater: text.split (/ \ r \ n | \ n | \ r /); haz lo mismo y es más corto y más rápido
Alejadro Xalabarder
7

El primero debería funcionar:

> "a\nb".split("\n");
[ 'a', 'b' ]
> var a = "test.js\nagain.js"
undefined
> a.split("\n");
[ 'test.js', 'again.js' ]
TimWolla
fuente
4

Hice un eolmódulo para trabajar con terminaciones de línea en nodos o navegadores. Tiene un método dividido como

var lines = eol.split(text)
ryanve
fuente