Cómo contar el número de líneas de una cadena en javascript


81

Quiero contar el número de líneas en una cadena

Intenté usar esta respuesta de stackoverflow:

lines = str.split("\r\n|\r|\n"); 
return  lines.length;

en esta cadena (que originalmente era un búfer):

 GET / HTTP/1.1
 Host: localhost:8888
 Connection: keep-alive
 Cache-Control: max-age=0
 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_2) AppleWebKit/535.2 (KHTML,like Gecko) Chrome/15.0.874.121 Safari/535.2
 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
 Accept-Encoding: gzip,deflate,sdch
 Accept-Language: en-US,en;q=0.8
 Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3

y por alguna razón obtuve líneas = '1'.

¿Alguna idea de cómo hacer que funcione?


3
@BookOfZeus "\ n" y "\ r" son manejados por su expresión regular. "\ n \ r" está mal.
bezmax

oh, lo veo, tienes razón mi mal
Libro de Zeus

Respondí una pregunta relacionada: "¿Cuál es la forma más rápida de probar una cantidad mínima de líneas o tokens?" stackoverflow.com/questions/39554154/…
Joe Lapp

@bezmax "\ n \ r" es necesario para el texto pegado.
Supreme Dolphin

@SupremeDolphin No, no lo es, al menos no para el ejemplo dado. Consulte en.wikipedia.org/wiki/… : "La línea de solicitud y otros campos de encabezado deben terminar con <CR> <LF>", es decir \r\n.
bezmax

Respuestas:


138

Usando una expresión regular puedes contar el número de líneas como

 str.split(/\r\n|\r|\n/).length

Alternativamente, puede probar el método dividido como se muestra a continuación.

var lines = $("#ptest").val().split("\n");  
alert(lines.length);

solución de trabajo: http://jsfiddle.net/C8CaX/


2
Falla para este caso de prueba: 'Roomy Below:\n\nStart again.'. Detecta 3 líneas, cuando, visualmente, hay 4. Esto se debe a que la división fusiona ambas líneas nuevas.
SimplGy

4
@SimplGy ¿Qué? No falla. Detecta 3 líneas porque hay 3 líneas, incluso visualmente. console.log('Roomy Below:\n\nStart again.')te da 3 líneas. Si dividir líneas nuevas fusionadas, esto no funcionaría:, console.log('Roomy Below:\n\nStart again.'.split('\n').join('\n'))pero lo hace y obtiene las mismas 3 líneas nuevamente.
Jools

1
Tienes razón Jools, arruiné este caso de recreación porque visualmente son 3 líneas (la primera \ n termina una línea de texto y la segunda crea una línea en blanco). Estoy seguro de que mi objeción se basó en un escenario de la vida real en algún momento, pero no tengo idea de qué en este momento.
SimplGy

4
Si el texto sólo toma '\ n' para los caracteres de nueva línea (por ejemplo, un <textarea>'s value), se puede considerar el uso TEXT.match(/^/mg).length.
Константин Ван

su respuesta es incorrecta, considere el caso "\ n \ n". Solo hay dos líneas. Pero su código da como resultado 3. Lo cual no es correcto.
Khamidulla

42

Otra solución breve y potencialmente más eficaz que la división es:

const lines = (str.match(/\n/g) || '').length + 1

esta es una solución mucho mejor
asmmahmud

3
como esta solución, pequeña mejora: en \r?realidad no está haciendo nada, (str.match(/\n/g) || '').lengthproduce el mismo resultado, ¿no?
Samuel Kirschner

Mejor solución, ya que la función de división crea una nueva matriz que es más pesada que esta solución.
hashed_name

ambos métodos crean una nueva matriz ... str.match devuelve una matriz y la división también ... El método de división devuelve una matriz de cadenas, pero str.match devuelve una matriz de objetos. Creo que un objeto ocupa más espacio en la memoria que una cadena ...
Bruno Desprez

claro ganador en el benchmark
Mila Nautikus

9

Para dividir usando una expresión regular, use /.../

lines = str.split(/\r\n|\r|\n/); 

9

Hmm sí ... lo que estás haciendo está absolutamente mal. Cuando lo digas str.split("\r\n|\r|\n"), intentará encontrar la cadena exacta "\r\n|\r|\n". Ahí es donde te equivocas. No hay tal ocurrencia en toda la cadena. Lo que realmente quieres es lo que sugirió David Hedlund:

lines = str.split(/\r\n|\r|\n/);
return lines.length;

La razón es que el método de división no convierte cadenas en expresiones regulares en JavaScript. Si desea usar una expresión regular, use una expresión regular.


7

Hice una prueba de rendimiento comparando split con regex, con una cadena y haciéndolo con un bucle for.

Parece que el bucle for es el más rápido.

NOTA: este código 'tal cual' no es útil para windows ni macos endline, pero debería estar bien para comparar el rendimiento.

Dividir con cuerda:

split('\n').length;

Dividir con expresiones regulares:

split(/\n/).length;

Dividir usando para:

var length = 0;
for(var i = 0; i < sixteen.length; ++i)
  if(sixteen[i] == s)
    length++;

http://jsperf.com/counting-newlines/2


gracioso, mi punto de referencia dice que el bucle for es más lento
Mila Nautikus

3

Hay tres opciones:

Usando jQuery (descargar desde el sitio web de jQuery ) - jquery.com

var lines = $("#ptest").val().split("\n");
return lines.length;

Usando Regex

var lines = str.split(/\r\n|\r|\n/);
return lines.length;

O una recreación de un bucle para cada

var length = 0;
for(var i = 0; i < str.length; ++i){
    if(str[i] == '\n') {
        length++;
    }
}
return length;


0

Mejor solución, ya que la función str.split ("\ n") crea una nueva matriz de cadenas dividida por "\ n", que es más pesada que str.match (/ \ n \ g). str.match (/ \ n \ g) crea una matriz de elementos coincidentes solamente. Que es "\ n" en nuestro caso.

var totalLines = (str.match(/\n/g) || '').length + 1;

0
 <script type="text/javascript">
      var multilinestr = `
        line 1
        line 2
        line 3
        line 4
        line 5
        line 6`;
      totallines = multilinestr.split("\n");
lines = str.split("\n"); 
console.log(lines.length);
</script>

eso funciona en mi caso

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.