Jak policzyć liczbę wierszy ciągu w javascript

84

Chcę policzyć liczbę wierszy w ciągu

próbowałem użyć tej odpowiedzi:

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

na tym ciągu (który pierwotnie był buforem):

 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

iz jakiegoś powodu otrzymałem linie = „1”.

masz pomysł, jak to działa?

Itzik984
źródło
3
@BookOfZeus "\ n" i "\ r" są obsługiwane przez jego wyrażenie regularne. „\ n \ r” jest po prostu błędne.
bezmax
och, widzę to, masz rację, moja wina
Book Of Zeus
Odpowiedziałem na pokrewne pytanie: „Jaki jest najszybszy sposób przetestowania minimalnej liczby wierszy lub tokenów?” stackoverflow.com/questions/39554154/…
Joe Lapp
@bezmax "\ n \ r" jest konieczne dla wklejonego tekstu.
Supreme Dolphin
@SupremeDolphin Nie, przynajmniej nie w podanym przykładzie. Zobacz en.wikipedia.org/wiki/… : "Wiersz żądania i inne pola nagłówka muszą kończyć się <CR> <LF>" \r\n.
bezmax

Odpowiedzi:

141

Używając wyrażenia regularnego, możesz policzyć liczbę wierszy jako

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

Alternatywnie możesz wypróbować metodę podziału, jak poniżej.

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

działające rozwiązanie: http://jsfiddle.net/C8CaX/

Pavan
źródło
2
Nie powiedzie się w tym przypadku testowego: 'Roomy Below:\n\nStart again.'. Wykrywa 3 linie, gdy wizualnie jest ich 4. Dzieje się tak, ponieważ podział łączy ze sobą obie nowe linie.
SimplGy
4
@SimplGy What? Nie zawodzi. Wykrywa 3 linie, ponieważ są 3 linie, nawet wizualnie. console.log('Roomy Below:\n\nStart again.')daje 3 linie. Jeśli podzielono scalone nowe linie, to nie zadziała:, console.log('Roomy Below:\n\nStart again.'.split('\n').join('\n'))ale działa i ponownie otrzymasz te same 3 linie.
Jools
1
Masz rację Jools, schrzaniłem ten przypadek ponownego tworzenia, ponieważ wizualnie są to 3 linie (pierwsza \ n kończy linię tekstu, a druga tworzy pustą linię). Jestem pewien, że w pewnym momencie mój sprzeciw był oparty na scenariuszu z prawdziwego życia, ale nie mam pojęcia, co w tym momencie.
SimplGy
4
Jeśli tekst zajmuje tylko „\ n” dla znaków nowej linii (np <textarea>„s value), można rozważyć użycie TEXT.match(/^/mg).length.
Константин Ван
Twoja odpowiedź jest nieprawidłowa, rozważ wielkość liter "\ n \ n". Są tylko dwie linie. Ale twój kod wyświetla 3. Co nie jest poprawne.
Khamidulla
45

Innym krótkim, potencjalnie wydajniejszym niż split, rozwiązaniem jest:

const lines = (str.match(/\n/g) || '').length + 1
ngryman
źródło
to jest o wiele lepsze rozwiązanie
asmmahmud
3
jak to rozwiązanie, mała poprawa: \r?tak naprawdę nic nie robi, (str.match(/\n/g) || '').lengthdaje ten sam wynik, prawda?
Samuel Kirschner
Lepsze rozwiązanie, ponieważ funkcja split tworzy nową tablicę, która jest cięższa niż to rozwiązanie.
hashed_name
obie metody tworzą nową tablicę… str.match zwraca Array, podobnie jak split… Metoda split zwraca Array of strings, ale str.match zwraca Array of objects. Myślę, że obiekt zajmuje więcej miejsca w pamięci niż ciąg…
Bruno Desprez
wyraźny zwycięzca w benchmarku
Mila Nautikus
9

Aby podzielić za pomocą wyrażenia regularnego, użyj /.../

lines = str.split(/\r\n|\r|\n/); 
David Hedlund
źródło
9

Hmm tak ... to co robisz jest absolutnie złe. Kiedy powiesz str.split("\r\n|\r|\n"), spróbuje znaleźć dokładny ciąg "\r\n|\r|\n". Tutaj się mylisz. Nie ma takiego zdarzenia w całym ciągu. To, czego naprawdę chcesz, zasugerował David Hedlund:

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

Powodem jest to, że metoda split nie konwertuje ciągów znaków na wyrażenia regularne w JavaScript. Jeśli chcesz użyć wyrażenia regularnego, użyj wyrażenia regularnego.

Aadit M Shah
źródło
7

Wykonałem test wydajności, porównując split z wyrażeniem regularnym, ze stringiem i robiąc to z pętlą for.

Wydaje się, że pętla for jest najszybsza.

UWAGA: ten kod „tak jak jest” nie jest przydatny dla systemu Windows ani macOS, ale powinien wystarczyć do porównania wydajności.

Podziel za pomocą sznurka:

split('\n').length;

Podziel z wyrażeniem regularnym:

split(/\n/).length;

Podziel za pomocą:

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

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

jperelli
źródło
zabawne, mój benchmark mówi, że pętla for jest najwolniejsza
Mila Nautikus
3

Istnieją trzy opcje:

Korzystanie z jQuery (do pobrania ze strony jQuery ) - jquery.com

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

Korzystanie z Regex

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

Lub odtworzenie pętli for each

var length = 0;
for(var i = 0; i < str.length; ++i){
    if(str[i] == '\n') {
        length++;
    }
}
return length;
Joe
źródło
1

Oto działające przykładowe skrzypce

Po prostu usuń dodatkowe \ r \ n i „|” z twojego rejestru ex.

Sandeep GB
źródło
1

Lepsze rozwiązanie, ponieważ funkcja str.split ("\ n") tworzy nową tablicę ciągów podzieloną przez "\ n", która jest cięższa niż str.match (/ \ n \ g). str.match (/ \ n \ g) tworzy tablicę tylko pasujących elementów. W naszym przypadku jest to „\ n”.

var totalLines = (str.match(/\n/g) || '').length + 1;
hashed_name
źródło
1
 <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>

to działa w moim przypadku

Krishna Kumar Jangid
źródło