Jak usunąć wszystkie znaki końca linii z łańcucha

440

Mam tekst w obszarze tekstowym i czytam go za pomocą atrybutu .value.

Teraz chciałbym usunąć wszystkie Enterłamanie wierszy (znak powstający po naciśnięciu ) z mojego tekstu, używając teraz .replace z wyrażeniem regularnym, ale jak wskazać łamanie linii w wyrażeniu regularnym?

Jeśli nie jest to możliwe, czy istnieje inny sposób?

Wingblade
źródło

Odpowiedzi:

501

To jest prawdopodobnie FAQ. W każdym razie, podziały linii (lepiej: nowe linie) mogą być jednym z Carriage Return (CR, \rna starszych komputerach Mac), Line Feed (LF \n, na Unices włącznie z Linuksem) lub CR, a następnie LF ( \r\n, na WinDOS). (W przeciwieństwie do innej odpowiedzi, nie ma to nic wspólnego z kodowaniem znaków.)

Dlatego najbardziej efektywnym RegExpdosłownym pasującym do wszystkich wariantów jest

/\r?\n|\r/

Jeśli chcesz dopasować wszystkie znaki nowej linii w ciągu, użyj dopasowania globalnego,

/\r?\n|\r/g

odpowiednio. Następnie postępuj zgodnie z replacemetodą opisaną w kilku innych odpowiedziach. (Prawdopodobnie nie chcesz usuwać nowych wierszy, ale zamień je na inne białe znaki, na przykład spację, aby słowa pozostały nienaruszone).

PointedEars
źródło
16
Ze względu na kompletność należy zauważyć, że w Unicode występują cztery różne nowe znaki wiersza: \u000alub \n, który jest wierszem; \u000dlub \r, który jest zwrotem przewozu; \u2028, separator linii; i \u2029separator akapitu. W praktyce opublikowany regex jest jednak w większości przypadków wystarczający.
Mathias Bynens
4
@MathiasBynens Dzięki, ale U + 2028 i U + 2029 wyraźnie nie stanowią podziału wiersza w HTML (4.01), na którym opiera się drzewo DOM i wartość rzeczywista obszaru tekstowego
PointedEars
5
@PointedEars Tak, ale serializacja HTML nie występuje przy .valuedynamicznym ustawianiu obszaru tekstowego , np textarea.value = 'a\u2029b'; textarea.value.charAt(1) == '\u2029'; // true. Ale jest to prawdopodobnie przypadek skrajny - jak powiedziałem, w większości przypadków regex jest wystarczający.
Mathias Bynens
2
@MathiasBynens Ponieważ U + 2028 i U + 2029 nie stanowią podziału wiersza w HTML (4.01), to przypisanie nie wyświetla dwóch wierszy w obszarze tekstowym w żadnej większej implementacji DOM i silniku układu. Więc nikt przy zdrowych zmysłach nie podjąłby się takiego zadania.
PointedEars
1
Musiałem uciec od ukośnika odwrotnego, aby to działało dla mnie, tj. TextIn.replace (/ (\\ r \\ n | \\ n | \\ r) / gm, ""). +1 nadal. Dziękuję
Crab Bucket
512

Sposób podziału linii różni się w zależności od kodowania systemu operacyjnego. Windows byłby \r\n, ale Linux po prostu używa, \na Apple używa \r.

Znalazłem to w podziale wiersza JavaScript :

someText = someText.replace(/(\r\n|\n|\r)/gm, "");

To powinno usunąć wszystkie rodzaje podziałów linii.

Eremita
źródło
18
Dlaczego jest posiadanie oddzielnej \r\n i \n i \r lepiej niż po prostu /[\n\r]/g? Z pewnością jest to wolniejsze niż powinno być, ponieważ wystarczy sprawdzić każdą postać w zestawie dwóch możliwych opcji.
Gone Coding
2
Podczas analizowania zwróciłem dane z memcached w node.js za pomocą / [\ n \ r] / g załatwiło sprawę dla mnie. Dzięki Gone Coding! Opcja w odpowiedzi zaszkodziła.
Kyle Coots,
111

var str = " \n this is a string \n \n \n"

console.log(str);
console.log(str.trim());

String.trim() usuwa białe znaki z początku i końca ciągów znaków ... w tym znaków nowej linii.

const myString = "   \n \n\n Hey! \n I'm a string!!!         \n\n";
const trimmedString = myString.trim();

console.log(trimmedString);
// outputs: "Hey! \n I'm a string!!!"

Oto przykładowe skrzypce: http://jsfiddle.net/BLs8u/

UWAGA! przycina tylko początek i koniec łańcucha, nie przerywa linii ani białych znaków na środku łańcucha.

RobW
źródło
34
Usuwa to tylko łamanie linii od początku i końca łańcucha. OP zapytał, jak usunąć WSZYSTKIE podziały linii.
Ian Walter
4
Tak, tylko dodając jako opcję.
RobW,
1
Pracowałem dla tego, czego potrzebowałem - początku i końca łańcucha. Dzięki!
Harlin,
46

Możesz użyć \nwyrażenia regularnego dla znaków nowej linii i \rzwrotów karetki.

var str2 = str.replace(/\n|\r/g, "");

Różne systemy operacyjne używają różnych zakończeń linii, z różnymi kombinacjami \ni \r. Ten regex zastąpi je wszystkie.

Kendall Frey
źródło
Myślę, że to zastąpi tylko pierwsze wystąpienie
Sebas
5
/\n|\r/gjest wydajniej napisany /[\n\r]/glub nawet /[\n\r]+/g. Unikaj zmiany, chyba że jest to absolutnie potrzebne.
PointedEars
Nie jestem pewien, czy jest to skarga. Robi to, co powiedziałem: usuwaj WSZYSTKO poza tym zakresem HEX. Jakie znaki zależą oczywiście od zestawu znaków, ale ten post dotyczył ASCII.
masi
22

Jeśli chcesz usunąć wszystkie znaki kontrolne, w tym CR i LF, możesz użyć tego:

myString.replace(/[^\x20-\x7E]/gmi, "")

Usunie wszystkie niedrukowalne znaki. To są wszystkie znaki NIE w przestrzeni HEX ASCII 0x20-0x7E. Zmodyfikuj zakres HEX w razie potrzeby.

masi
źródło
2
Spowoduje to również usunięcie niektórych znaków narodowych z języków innych niż angielski ....
smentek
21

Najprostszym rozwiązaniem byłoby:

let str = '\t\n\r this  \n \t   \r  is \r a   \n test \t  \r \n';
str.replace(/\s+/g, ' ').trim();
console.log(str); // logs: "this is a test"

.replace()z /\s+/gregexp zmienia wszystkie grupy białych znaków na jedną spację w całym ciągu, a następnie .trim()usuwamy wszystkie przekraczające białe spacje przed i po tekście.

Są uważane za znaki białych znaków:
[ \f\n\r\t\v​\u00a0\u1680​\u2000​-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff]

Freezystem
źródło
Wspaniale, ale działam, zmieniając przypisanie zmiennej:str = str.replace(/\s+/g, ' ').trim();
Fred K
15
var str = "bar\r\nbaz\nfoo";

str.replace(/[\r\n]/g, '');

>> "barbazfoo"
Gordon Freeman
źródło
15

Aby usunąć nowe znaki linii, użyj tego:

yourString.replace(/\r?\n?/g, '')

Następnie możesz przyciąć ciąg, aby usunąć spacje wiodące i końcowe:

yourString.trim()
Si7ius
źródło
6

Odpowiedź dostarczona przez PointedEars to wszystko, czego większość z nas potrzebuje. Ale podążając za odpowiedzią Mathiasa Bynensa, pojechałem na Wikipedię i znalazłem to: https://en.wikipedia.org/wiki/Newline .

Poniżej znajduje się funkcja rozwijana, która implementuje wszystko, co powyższa strona Wiki uważa za „nową linię” w momencie tej odpowiedzi.

Jeśli coś nie pasuje do twojej skrzynki, po prostu ją usuń. Ponadto, jeśli szukasz wydajności, może to nie być to, ale w przypadku szybkiego narzędzia, które wykona zadanie w każdym przypadku, powinno to być przydatne.

// replaces all "new line" characters contained in `someString` with the given `replacementString`
const replaceNewLineChars = ((someString, replacementString = ``) => { // defaults to just removing
  const LF = `\u{000a}`; // Line Feed (\n)
  const VT = `\u{000b}`; // Vertical Tab
  const FF = `\u{000c}`; // Form Feed
  const CR = `\u{000d}`; // Carriage Return (\r)
  const CRLF = `${CR}${LF}`; // (\r\n)
  const NEL = `\u{0085}`; // Next Line
  const LS = `\u{2028}`; // Line Separator
  const PS = `\u{2029}`; // Paragraph Separator
  const lineTerminators = [LF, VT, FF, CR, CRLF, NEL, LS, PS]; // all Unicode `lineTerminators`
  let finalString = someString.normalize(`NFD`); // better safe than sorry? Or is it?
  for (let lineTerminator of lineTerminators) {
    if (finalString.includes(lineTerminator)) { // check if the string contains the current `lineTerminator`
      let regex = new RegExp(lineTerminator.normalize(`NFD`), `gu`); // create the `regex` for the current `lineTerminator`
      finalString = finalString.replace(regex, replacementString); // perform the replacement
    };
  };
  return finalString.normalize(`NFC`); // return the `finalString` (without any Unicode `lineTerminators`)
});
futz.co
źródło
3
Po pierwsze - dla osób, które nie korzystają z JS - obsługa „większości” smaków RE, \Rczyli „wszystkich” kanałów. Po drugie - dlaczego nie po prostusomeString.replace(new RegExp(lineTerminators.join('|')), '');
SamWhan
@ClasG, masz rację. Myślę, że mój tok myślenia, gdy to napisałem, dotyczył tylko replace()tego, lineTerminatorsktóry istniał w ciągu ze względu na wydajność.
futz.co
5

Podziałem wiersza w wyrażeniu regularnym jest \ n, więc skrypt byłby

var test = 'this\nis\na\ntest\nwith\newlines';
console.log(test.replace(/\n/g, ' '));
h2ooooooo
źródło
5

Dodaję swoją odpowiedź, jest to tylko dodatek do powyższego, ponieważ dla mnie wypróbowałem wszystkie opcje / n i nie działało, zobaczyłem, że mój tekst pochodzi z serwera z podwójnym ukośnikiem, więc użyłem tego:

var fixedText = yourString.replace(/(\r\n|\n|\r|\\n)/gm, '');
chaya D.
źródło
5

KORZYSTAJ Z PONIŻSZEJ FUNKCJI I UŁATWIAJ SWOJE ŻYCIE

Najłatwiejszym podejściem jest użycie wyrażeń regularnych do wykrywania i zastępowania znaków nowej linii w ciągu. W tym przypadku używamy funkcji replace wraz z ciągiem do zamiany, który w naszym przypadku jest pustym ciągiem.

function remove_linebreaks( var message ) {
    return message.replace( /[\r\n]+/gm, "" );
}

W powyższym wyrażeniu g i m oznaczają flagi globalne i wielowierszowe

vishu2124
źródło
2

Wypróbuj następujący kod. Działa na wszystkich platformach.

var break_for_winDOS = 'test\r\nwith\r\nline\r\nbreaks';
var break_for_linux = 'test\nwith\nline\nbreaks';
var break_for_older_mac = 'test\rwith\rline\rbreaks';

break_for_winDOS.replace(/(\r?\n|\r)/gm, ' ');
//output
'test with line breaks'

break_for_linux.replace(/(\r?\n|\r)/gm, ' ');
//output
'test with line breaks'

break_for_older_mac.replace(/(\r?\n|\r)/gm, ' ');
// Output
'test with line breaks'
Robson Morais Santos
źródło
0

Na komputerze Mac wystarczy użyć \nwyrażenia regularnego, aby dopasować podziały wierszy. Tak więc kod będzie string.replace(/\n/g, '')wyglądał następująco: ps: g następujące oznacza, że ​​pasuje do wszystkich zamiast tylko pierwszego.

Tak będzie w systemie Windows \r\n.

kobako
źródło