Dopasuj podziały wierszy - \ n czy \ r \ n?

159

Pisząc tę odpowiedź , musiałem dopasować wyłącznie na łamach linii zamiast używać opcji s-flag ( dotall- kropka odpowiada podziałom linii).

Witryny używane zwykle do testowania wyrażeń regularnych zachowują się inaczej, gdy próbują dopasować na \nlub \r\n.

Zauważyłem

  • Regex101 dopasowuje tylko podziały wierszy \n
    ( przykład - usuń \ri pasuje)

  • RegExr dopasowuje podziały linii ani włączone, \n ani włączone \r\n
    i nie mogę znaleźć czegoś, co pasowałoby do podziału linii, z wyjątkiem m-flag i \s
    ( przykład )

  • Debuggex zachowuje się jeszcze bardziej inaczej:
    w tym przykładzie pasuje tylko do \r\n, podczas gdy
    tutaj pasuje tylko do \n, z tymi samymi flagami i określonym silnikiem

W pełni zdaję sobie sprawę z opcji m-flag (multiline - ^dopasowuje początek i $koniec wiersza), ale czasami nie jest to opcja. To samo \sdotyczy również tabulatorów i spacji.

Moja myśl o użyciu znaku nowej linii Unicode ( \u0085) nie powiodła się, więc:

  1. Czy istnieje bezpieczny sposób zintegrowania dopasowania w miejscu zakończenia wiersza (najlepiej niezależnie od używanego języka) z wyrażeniem regularnym?
  2. Dlaczego wyżej wymienione strony zachowują się inaczej (zwłaszcza Debuggex, dopasowywanie tylko \nraz i raz tylko \r\n)?
KeyNone
źródło
15
Możesz spróbować [\r\n]+- lub coś takiego
Iłya Bursov
3
Używam: \r?\naby dopasować zarówno sekwencje zakończenia linii, jak \r\ni \nsekwencje zakończenia linii. Nie działa dla starej \rskładni Maca, ale ta jest obecnie dość rzadka.
ridgerunner
6
Hej, jestem założycielem debuggex. Wygląda to na błąd (w przypadku debuggex nie mogę mówić w imieniu innych). Dodałem problem z wysoką ceną odnoszący się do tego pytania. Dojdziemy do tego jak najszybciej - obecnie koncentrujemy wszystkie nasze (bardzo ograniczone) zasoby na wprowadzeniu kolejnego produktu.
Sergiu Toarca
2
@ridgerunner, aby dodać do tego składnię Maca, możesz zrobić (\ r? \ n | \ r), co jest podobne do odpowiedzi Petera van der Wala poniżej, ale bardziej zwarte (10 znaków w porównaniu z 12 znakami).
Doktor J,

Odpowiedzi:

220

Odpowiem w przeciwnym kierunku.

2) Aby uzyskać pełne wyjaśnienie \ri \nmuszę odnieść się do tego pytania, które jest o wiele bardziej kompletne niż to, które opiszę tutaj: Różnica między \ n i \ r?

Krótko mówiąc, Linux używa \nnowej linii, Windows \r\ni starych komputerów Mac \r. Tak więc istnieje wiele sposobów na napisanie nowej linii. Twoje drugie narzędzie (RegExr) pasuje na przykład na singlu \r.

1), [\r\n]+jak sugerował Ilya, będzie działać, ale będzie również pasować do wielu kolejnych nowych linii. (\r\n|\r|\n)jest bardziej poprawne.

Peter van der Wal
źródło
Więc \r/ \nzależą od systemu operacyjnego - to można wiedzieć (;)) - ale dlaczego dwa przykłady debuggex pasują do siebie raz w \ r \ n i raz na \ n? Przynajmniej nie ma różnicy (w przykładach) widocznej dla mnie.
KeyNone
Najprawdopodobniej dlatego, że skopiowałeś jeden z edytora tekstu Windows, a drugi napisałeś bezpośrednio do obszaru tekstowego debuggex. Każdy używał innego podziału wiersza.
OGHaza,
1
Rzeczywiście, ponieważ w Twoim trzecim przykładzie (Senior men ...) jest \r\nw tekście (jeśli klikniesz prawym przyciskiem myszy i pokażesz źródło, znajdziesz {{Infobox XC Championships\r\n|Name =gdzieś). Drugie narzędzie jest napisane we Flashu i podczas czytania strony z informacjami jest nieco błędne ze znakami nowej linii.
Peter van der Wal
1
(\r\n|\r|\n)można napisać prościej jako\r\n?
Asad Saeeduddin
2
@AsadSaeeduddin Nie, nie może. To nie będzie pasować do końcówki linii Unix\n
Peter van der Wal
12

Masz różne zakończenia linii w przykładowych tekstach w Debuggex. Szczególnie interesujące jest to, że Debuggex zdaje się zidentyfikować styl zakończenia linii, którego użyłeś jako pierwszy i konwertuje wszystkie dodatkowe zakończenia linii wprowadzone na ten styl.

Użyłem Notepad ++ do wklejenia przykładowego tekstu w formacie Unix i Windows do Debuggex, a cokolwiek wkleiłem jako pierwsze, jest tym, z czym utknęła ta sesja Debuggex.

Dlatego przed wklejeniem go do Debuggex należy przepłukać tekst w edytorze tekstu. Upewnij się, że wklejasz żądany styl. Debuggex domyślnie ustawia styl uniksowy (\ n).

Poza tym NEL (\ u0085) to coś zupełnie innego: https://en.wikipedia.org/wiki/Newline#Unicode

(\r?\n)obejmie systemy Unix i Windows. Będziesz potrzebować czegoś bardziej złożonego, na przykład (\r\n|\r|\n), jeśli chcesz dopasować również stary Mac.

Duńczyk
źródło
Bardzo interesujący punkt dotyczący debuggex! Dzięki za zwrócenie uwagi \ u0085, zostałem wprowadzony w błąd!
KeyNone,
3

W PCRE \Rpasuje \n, \ri \r\n.

Cwazy Paving
źródło
Nie ma wątpliwości
Sandwell
1
@Sandwell: Przepraszam, nie rozumiem, to nie jest pytanie, to odpowiedź, prostsza niż(\r\n|\r|\n)
Toto
2

Dotyczy to tylko pytania 1.

Mam aplikację działającą w systemie Windows i używającą wieloliniowego edytora MFC.
Okno edytora oczekuje podziałów wierszy CRLF, ale muszę przeanalizować wprowadzony tekst za
pomocą kilku naprawdę dużych / paskudnych wyrażeń regularnych .

Nie chciałem się tym stresować podczas pisania wyrażenia regularnego, więc w
końcu normalizowałem tam iz powrotem między parserem a edytorem, aby
po prostu używać wyrażeń regularnych \n. Wklejam również operacje wklejania i konwertuję je na pola.

Nie zajmuje to dużo czasu.
To jest to, czego używam.

 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" );
 }

źródło
2

W Pythonie:

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

lub bardziej rygorystyczne:

# https://docs.python.org/3/library/stdtypes.html#str.splitlines
str.splitlines()
Keelung
źródło