it-swarm.com.de

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

Beim Schreiben von dieser Antwort musste ich ausschließlich mit Zeilenumbrüchen übereinstimmen, anstatt das s- Flag zu verwenden (dotall - Punkt entspricht Zeilenumbrüchen). 

Die Websites, die normalerweise zum Testen regulärer Ausdrücke verwendet werden, verhalten sich unterschiedlich, wenn sie versuchen, auf \n oder \r\n abzugleichen.

Mir ist aufgefallen

  • Regex101 vergleicht nur Zeilenumbrüche in \n
    ( Beispiel - Lösche \r und es stimmt überein) 

  • RegExr entspricht Zeilenumbrüchen weder in \nnoch in \r\n
    und ich kann nichts finden, damit es mit einem Zeilenumbruch übereinstimmt, außer der m- Flagge und \s
    ( Beispiel )

  • Debuggex verhält sich noch anders:
    in diesem Beispiel stimmt nur mit \r\n überein, während
    hier stimmt nur mit \n überein, wobei dieselben Flags und Engine angegeben sind

Ich kenne die Variable m- vollständig (Multiline - bewirkt, dass ^ dem Anfang und $ dem Ende einer Zeile entspricht), aber manchmal ist dies keine Option. Dasselbe gilt für \s, da auch Tabs und Leerzeichen übereinstimmen. 

Mein Gedanke, das Unicode-Zeilenvorschubzeichen ( \u0085 ) zu verwenden, war nicht erfolgreich.

  1. Gibt es eine ausfallsichere Möglichkeit, das Match auf einem Zeilenumbruch (vorzugsweise unabhängig von der verwendeten Sprache) in einen regulären Ausdruck zu integrieren?
  2. Warum verhalten sich die oben genannten Sites anders (insbesondere Debuggex, nur einmal auf \n und einmal nur auf \r\n)?
94
Basti M

Antworte in entgegengesetzter Richtung;)

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

Um es kurz zu machen: Linux verwendet\n für eine neue Zeile, Windows\r\n und alte Macs\r. Es gibt also mehrere Möglichkeiten, einen Zeilenumbruch zu schreiben. Ihr zweites Tool (RegExr) stimmt beispielsweise mit dem einzelnen\r überein.

1) [\r\n]+, wie Ilya vorschlug, funktioniert zwar, passt aber auch zu mehreren aufeinander folgenden Zeilen. (\r\n|\r|\n) ist richtiger.

133

In den Beispieltexten in Debuggex gibt es unterschiedliche Zeilenenden. Interessant ist vor allem, dass Debuggex anscheinend den zuerst verwendeten Zeilenendstil identifiziert hat und alle zusätzlich eingegebenen Zeilenenden in diesen Stil konvertiert.

Ich habe Notepad ++ verwendet, um Beispieltext im Unix- und Windows-Format in Debuggex einzufügen. Unabhängig davon, was ich zuerst eingefügt habe, ist diese Sitzung von Debuggex dabei geblieben.

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

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

(\r?\n) behandelt Unix und Windows. Sie benötigen etwas komplexeres wie (\r\n|\r|\n), wenn Sie auch einen alten Mac verwenden möchten.

7
Dane

Dies gilt nur für Frage 1.

Ich habe eine App, die unter Windows läuft und eine mehrzeilige MFC-Editorbox verwendet.
Das Editorfeld erwartet CRLF-Zeilenumbrüche, aber ich muss den eingegebenen Text analysieren
mit einigen wirklich großen/bösen Regexen. 

Ich wollte mich beim Schreiben der Regex nicht darum kümmern
Ich normalisierte hin und her zwischen dem Parser und dem Editor, so dass
Die Regexen verwenden einfach \n. Ich fange auch Einfügeoperationen ein und konvertiere sie für die Boxen. 

Das dauert nicht lange.
Das verwende 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" );
 }
1
sln

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()
0
Keelung