Abbina interruzioni di riga - \ n o \ r \ n?


159

Durante la stesura di questa risposta , ho dovuto corrispondere esclusivamente alle interruzioni di sriga invece di utilizzare -flag ( dotall- il punto corrisponde alle interruzioni di riga ).

I siti solitamente utilizzati per testare le espressioni regolari si comportano in modo diverso quando si tenta di abbinare su \no \r\n.

Ho notato

  • Regex101 corrisponde alle interruzioni di riga solo su \n
    ( esempio : elimina \re corrisponde)

  • RegExr non corrisponde a interruzioni di riga su \n su \r\n
    e non riesco a trovare qualcosa per farlo corrispondere a un'interruzione di linea, ad eccezione di m-flag e \s
    ( esempio )

  • Debuggex si comporta in modo ancora più diverso:
    in questo esempio corrisponde solo su \r\n, mentre
    qui corrisponde solo su \n, con gli stessi flag e motore specificati

Sono pienamente consapevole di m-flag (multilinea - fa ^corrispondere l'inizio e $la fine di una riga), ma a volte questa non è un'opzione. Lo stesso con \s, poiché corrisponde anche a schede e spazi.

Il mio pensiero di utilizzare il carattere unicode newline ( \u0085) non ha avuto successo, quindi:

  1. Esiste un modo sicuro per integrare la corrispondenza in un'interruzione di linea (preferibilmente indipendentemente dalla lingua utilizzata) in un'espressione regolare?
  2. Perché i siti di cui sopra si comportano in modo diverso (in particolare Debuggex, facendo corrispondere una volta sola \ne una volta sola \r\n)?

15
Puoi provare [\r\n]+- o qualcosa del genere
Iłya Bursov il

3
Io uso: \r?\nper abbinare entrambi \r\ne \ndi terminazione della linea sequenze. Non funziona per la vecchia \rsintassi Mac, ma quella è piuttosto rara in questi giorni.
ridgerunner,

6
Ehi, sono il fondatore di debuggex. Sembra un bug (per debuggex, non posso parlare per gli altri). Ho aggiunto un problema di alto livello che fa riferimento a questa domanda. Ci arriveremo al più presto - al momento stiamo concentrando tutte le nostre risorse (molto limitate) sul lancio di un altro prodotto.
Sergiu Toarca,

2
@ridgerunner per aggiungere la sintassi di Mac a questo, potresti farlo (\ r? \ n | \ r), che è simile alla risposta di Peter van der Wal di seguito ma più compatta (10 caratteri contro 12 caratteri).
Doktor J,

Risposte:


220

Risponderò nella direzione opposta.

2) Per una spiegazione completa su \re \ndevo fare riferimento a questa domanda, che è molto più completa di quanto posterò qui: Differenza tra \ n e \ r?

Per farla breve, Linux utilizza \nper una nuova linea, Windows \r\ne vecchi Mac \r. Quindi ci sono diversi modi per scrivere una nuova riga. Ad esempio, il secondo strumento (RegExr) corrisponde al singolo \r.

1) [\r\n]+come suggerito da Ilya funzionerà, ma corrisponderà anche a più nuove righe consecutive. (\r\n|\r|\n)è più corretto.


Quindi, \r/ \ndipendono dal sistema operativo - è una cosa che si potrebbe sapere (;)) - ma perché i due esempi debuggex corrispondono una volta su \ r \ n e una volta su \ n? Almeno non c'è differenza (negli esempi) visibile per me.
KeyNone,

Molto probabilmente perché ne hai copiato uno dall'editor di testo di Windows e l'altro che hai scritto direttamente nell'area di testo di debuggex. Ciascuno utilizzava diverse interruzioni di riga.
OGHaza,

1
In effetti, perché nel tuo terzo esempio (gli uomini Senior ...) c'è un \r\ntesto (se fai clic con il pulsante destro del mouse e mostri la fonte, troverai {{Infobox XC Championships\r\n|Name =da qualche parte). Il secondo strumento è scritto in Flash e mentre leggi la pagina di informazioni un po 'buggy con i caratteri di nuova riga.
Peter van der Wal,

1
(\r\n|\r|\n)può essere scritto più semplicemente come\r\n?
Asad Saeeduddin,

2
@AsadSaeeduddin No non può. Non corrisponderà al finale di linea Unix\n
Peter van der Wal,

12

Hai diversi finali di riga nei testi di esempio in Debuggex. Ciò che è particolarmente interessante è che Debuggex sembra aver identificato quale stile di fine linea hai usato per primo, e converte tutte le terminazioni di linea aggiuntive inserite in quello stile.

Ho usato Notepad ++ per incollare il testo di esempio in formato Unix e Windows in Debuggex, e quello che ho incollato per primo è quello con cui quella sessione di Debuggex è rimasta bloccata.

Quindi, dovresti lavare il tuo testo attraverso il tuo editor di testo prima di incollarlo in Debuggex. Assicurati di incollare lo stile che desideri. Debuggex è impostato di default sullo stile Unix (\ n).

Inoltre, NEL (\ u0085) è qualcosa di completamente diverso: https://en.wikipedia.org/wiki/Newline#Unicode

(\r?\n)coprirà Unix e Windows. Avrai bisogno di qualcosa di più complesso, come (\r\n|\r|\n), se vuoi abbinare anche il vecchio Mac.


Punto molto interessante su debuggex! Inoltre, grazie per aver sottolineato \ u0085, sono stato fuorviato lì!
KeyNone,

3

Nelle \Rpartite PCRE \n, \re \r\n.


Non c'è dubbio
Sandwell,

1
@Sandwell: Scusa, non ti capisco, questa non è una domanda, è una risposta, più semplice di(\r\n|\r|\n)
Tot

2

Questo vale solo per la domanda 1.

Ho un'app che funziona su Windows e utilizza una casella di editor MFC multilinea.
La finestra dell'editor prevede interruzioni di riga CRLF, ma ho bisogno di analizzare il testo attirato
da alcune regex davvero grandi / cattive.

Non volevo insistere su questo durante la scrittura di regex, quindi
ho finito per normalizzare avanti e indietro tra il parser e l'editor in modo che
i regex usino semplicemente \n. Inoltre intrappolo le operazioni di incolla e le converto per le scatole.

Questo non richiede molto tempo.
Questo è quello che uso.

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

2

In Python:

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

o più rigoroso:

# https://docs.python.org/3/library/stdtypes.html#str.splitlines
str.splitlines()
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.