Zeilenumbrüche abgleichen - \ n oder \ r \ n?

159

Während ich diese Antwort schrieb , musste ich mich ausschließlich mit Zeilenumbrüchen sbefassen, anstatt das Flag -flag zu verwenden ( dotall- Punkt entspricht Zeilenumbrüchen).

Die Sites, die normalerweise zum Testen regulärer Ausdrücke verwendet werden, verhalten sich anders, wenn versucht wird, auf \noder übereinzustimmen \r\n.

Ich bemerkte

  • Regex101 stimmt nur mit Zeilenumbrüchen überein \n
    ( Beispiel - Löschen \rund es stimmt überein)

  • RegExr Spiele Zeilenumbrüche weder auf \n noch auf \r\n
    und ich kann nicht etwas finden , um es einen Zeilenumbruch zu machen entspricht, mit Ausnahme des m-Kennzeichen und \s
    ( Beispiel )

  • Debuggex verhält sich noch anders:
    In diesem Beispiel stimmt es nur mit überein \r\n, während es
    hier nur \nmit denselben Flags und derselben Engine übereinstimmt

Ich bin mir der m-flag (mehrzeilig - entspricht ^dem Anfang und $dem Ende einer Zeile) voll bewusst , aber manchmal ist dies keine Option. Gleiches \sgilt für Tabulatoren und Leerzeichen.

Mein Gedanke, das Unicode-Zeilenumbruchzeichen ( \u0085) zu verwenden, war nicht erfolgreich, also:

  1. Gibt es eine ausfallsichere Möglichkeit, die Übereinstimmung bei einem Zeilenumbruch (vorzugsweise unabhängig von der verwendeten Sprache) in einen regulären Ausdruck zu integrieren?
  2. Warum verhalten sich die oben genannten Websites anders (insbesondere Debuggex, das nur \neinmal und nur einmal übereinstimmt \r\n)?
KeyNone
quelle
15
Sie können versuchen [\r\n]+- oder so etwas
Iłya Bursov
3
Ich benutze: \r?\num beide \r\nund \nZeilenabschlusssequenzen abzugleichen. Es funktioniert nicht für die alte \rMac-Syntax, aber diese ist heutzutage ziemlich selten.
Ridgerunner
6
Hey, ich bin der Gründer von Debuggex. Dies sieht aus wie ein Fehler (für Debuggex kann ich nicht für die anderen sprechen). Ich habe ein High-Pri-Problem hinzugefügt, das auf diese Frage verweist. Wir werden so schnell wie möglich darauf zugreifen - wir konzentrieren derzeit alle unsere (sehr begrenzten) Ressourcen auf die Einführung eines anderen Produkts.
Sergiu Toarca
2
@ridgerunner, um die Mac-Syntax hinzuzufügen, könnten Sie tun (\ r? \ n | \ r), was der Antwort von Peter van der Wal unten ähnelt, aber kompakter ist (10 Zeichen gegenüber 12 Zeichen).
Doktor J

Antworten:

220

Ich werde in die entgegengesetzte Richtung antworten.

2) Für eine vollständige Erklärung über \rund \nich muss auf diese Frage verweisen, die weitaus vollständiger ist, als ich hier posten werde: Unterschied zwischen \ n und \ r?

Kurz gesagt, Linux verwendet \nfür eine neue Linie, Windows \r\nund alte Macs \r. Es gibt also mehrere Möglichkeiten, eine neue Zeile zu schreiben. Ihr zweites Tool (RegExr) stimmt beispielsweise mit der Single überein \r.

1) [\r\n]+wie von Ilya vorgeschlagen, funktioniert, passt aber auch zu mehreren aufeinanderfolgenden neuen Zeilen. (\r\n|\r|\n)ist korrekter.

Peter van der Wal
quelle
Also, \r/ \nsind abhängig vom Betriebssystem - das ist eine Sache, die man vielleicht kennt (;)) - aber warum stimmen die beiden Debuggex-Beispiele einmal auf \ r \ n und einmal auf \ n überein? Zumindest ist für mich kein Unterschied (in den Beispielen) sichtbar.
KeyNone
Höchstwahrscheinlich, weil Sie einen aus Ihrem Windows-Texteditor kopiert und den anderen direkt in den Debuggex-Textbereich geschrieben haben. Jeder verwendete unterschiedliche Zeilenumbrüche.
OGHaza
1
In der Tat, weil in Ihrem dritten Beispiel (dem der älteren Männer ...) ein \r\nText enthalten ist (wenn Sie mit der rechten Maustaste klicken und die Quelle anzeigen, finden Sie sie {{Infobox XC Championships\r\n|Name =irgendwo). Das zweite Tool ist in Flash geschrieben und beim Lesen der About-Seite etwas fehlerhaft mit Zeilenumbrüchen.
Peter van der Wal
1
(\r\n|\r|\n)kann einfacher geschrieben werden als\r\n?
Asad Saeeduddin
2
@AsadSaeeduddin Nein, das kann es nicht. Es wird nicht mit dem Unix-Zeilenende übereinstimmen\n
Peter van der Wal
12

Sie haben unterschiedliche Zeilenenden in den Beispieltexten in Debuggex. Besonders interessant ist, dass Debuggex offenbar festgestellt hat, welchen Zeilenendstil Sie zuerst verwendet haben, und alle zusätzlichen Zeilenenden, die in diesen Stil eingegeben wurden, konvertiert.

Ich habe Notepad ++ verwendet, um Beispieltext im Unix- und Windows-Format in Debuggex einzufügen, und was auch immer ich zuerst eingefügt habe, ist das, woran diese Debuggex-Sitzung festhielt.

Sie sollten Ihren Text also in Ihrem Texteditor waschen, bevor Sie ihn in Debuggex einfügen. Stellen Sie sicher, dass Sie den gewünschten Stil einfügen. Debuggex verwendet standardmäßig den Unix-Stil (\ n).

Auch NEL (\ u0085) ist etwas ganz anderes: https://en.wikipedia.org/wiki/Newline#Unicode

(\r?\n)wird Unix und Windows abdecken. Sie benötigen etwas Komplexeres, (\r\n|\r|\n)wenn Sie auch mit dem alten Mac übereinstimmen möchten.

Däne
quelle
Sehr interessanter Punkt über Debuggex! Vielen Dank, dass Sie auf \ u0085 hingewiesen haben und dort irregeführt wurden!
KeyNone
3

In PCRE \Rentspricht \n, \rund \r\n.

Cwazy Pflasterung
quelle
Keine Frage
Sandwell
1
@ Sandwell: Entschuldigung, ich verstehe dich nicht, das ist keine Frage, es ist eine Antwort, einfacher als(\r\n|\r|\n)
Toto
2

Dies gilt nur für Frage 1.

Ich habe eine App, die unter Windows ausgeführt wird und ein mehrzeiliges MFC-Editorfeld verwendet.
Das Editor-Feld erwartet CRLF-Zeilenumbrüche, aber ich muss den eingegebenen Text
mit einigen wirklich großen / bösen regulären Ausdrücken analysieren.

Ich wollte mich beim Schreiben der Regex nicht darum kümmern, also
normalisierte ich mich zwischen Parser und Editor hin und her, damit
die Regexs nur verwendet werden \n. Ich fange auch Einfügevorgänge ein und konvertiere sie für die Boxen.

Das braucht nicht viel Zeit.
Das benutze ich.

 boost::regex  CRLFCRtoLF (
     " \\r\\n | \\r(?!\\n) "
     , MODx);

 boost::regex  CRLFCRtoCRLF (
     " \\r\\n?+ | \\n "
     , MODx);


 // Convert (All style) linebreaks to linefeeds 
 // ---------------------------------------
 void ReplaceCRLFCRtoLF( string& strSrc, string& strDest )
 {
    strDest  = boost::regex_replace ( strSrc, CRLFCRtoLF, "\\n" );
 }

 // Convert linefeeds to linebreaks (Windows) 
 // ---------------------------------------
 void ReplaceCRLFCRtoCRLF( string& strSrc, string& strDest )
 {
    strDest  = boost::regex_replace ( strSrc, CRLFCRtoCRLF, "\\r\\n" );
 }

quelle
2

In Python:

# as Peter van der Wal's answer
re.split(r'\r\n|\r|\n', text, flags=re.M) 

oder strenger:

# https://docs.python.org/3/library/stdtypes.html#str.splitlines
str.splitlines()
Keelung
quelle