2010-07-10 10 views
22

Sono sicuro che questo è stato chiesto prima, ma non riesco a trovarlo.Che cos'è una regex cross platform per la rimozione delle interruzioni di riga?

Fondamentalmente, supponendo che si stia analizzando un file di testo di origine sconosciuta e si desideri sostituire interruzioni di riga con qualche altro delimitatore, è questa la migliore espressione regolare, o ce n'è un'altra?

(\r\n)|(\n)|(\r)

+1

vi preoccupate per le interruzioni di riga-Mac-stile vecchio ('\ R'), oppure solo su Unix e Windows (' \ n' e '\ r \ n')? –

+1

possibile duplicato di [Espressione regolare per abbinare caratteri di nuova riga multipiattaforma] (http://stackoverflow.com/questions/1331815/regolare-espressione-per-match-cross-platform-newline-characters) – Amarghosh

risposta

0

sufficiente sostituire /[\r\n]+/g con una stringa vuota "".

Sostituirà tutto \r e \n indipendentemente dall'ordine in cui appaiono nella stringa.

+0

Questo sostituirà qualsiasi numero di interruzioni di riga con un token sostitutivo. –

+0

@Andreas Vuole rimuovere le interruzioni di riga. – Amarghosh

+1

Beh, vuole sostituirli con un altro delimitatore ... –

20

eseguire controllo se il motore regex supporta \R come una classe di caratteri stenografia e non avrà bisogno di essere interessati con le combinazioni diverse a capo/avanzamento riga Unicode. Se implementato correttamente, è possibile abbinare in modo trasparente tutte le varie terminazioni di linea ascii o Unicode utilizzando \R.

In Unicode è necessario per rilevare NEL (/ 390 linea OS fine, \ x85) LS (linea di separazione, \ x2028) e PS (Paragrafo separatore, \ x2029) se si vuole essere piattaforma completamente cross in questi giorni.

È discutibile se LS, NEL e PS debbano essere trattati come interruzioni di linea, terminazioni di linea o spazi bianchi. Lo standard XML 1.0, ad esempio, does not recognize NEL come carattere di interruzione di riga. ECMAScript considera LS e PS come interruzioni di riga ma NEL come spazio vuoto. Perl unicode regexs tratteranno VT, FF, CR, CRLF, NEL, LS e PS come interruzioni di riga al fine di ^ e $ caratteri meta espressioni regolari.

Il numero Unicode Implementation Guide (sezione 5.8 e tabella 5.3) è probabilmente la migliore scommessa su quale sia il trattamento definitivo di cosa sia una "nuova linea".

Se siete preoccupati solo con ascii con le varianti classiche DOS/Windows/Unix/Mac, l'espressione regolare equivale a \R è (?>\r\n|[\r\n])

In Unicode, l'equivalente di \R è (?>\r\n|\n|\x0b|\f|\r|\x85|\x2028|\x2029) Il \x0b in C'è una verticale scheda; ancora una volta, questo può o meno adattarsi alla definizione di un'interruzione di riga, ma corrisponde alla raccomandazione di Unicode Implantation. (FF o \x0C non è incluso nella regex poiché un Feed modulo è una nuova pagina, non una nuova riga nella definizione.)

+0

"utf8" nella tua risposta dovrebbe essere "Unicode". UTF-8 è semplicemente una delle codifiche di caratteri Unicode. –

+0

Hai ragione, ma i documenti a cui mi riferivo (manuale PCRE) avevano lo stesso problema! Modifica apportata ... – dawg

+2

In Java, la parte '\ x2028 | \ x2029' deve essere scritta' \ u2028 | \ u2029', perché '\ xhh' viene utilizzata solo per valori di carattere esadecimale a 2 cifre, mentre' \ uhhhh' viene utilizzato per valori di carattere esadecimale a 4 cifre. –

2

La regex di trovare qualsiasi terminatore di linea Unicode dovrebbe essere (?>\x0D\x0A?|[\x0A-\x0C\x85\x{2028}\x{2029}]) piuttosto che come drewk ha scritto, almeno in Perl. Preso direttamente dalla documentazione perl 5.10.0 (è stato rimosso nelle versioni successive). Nota le parentesi dopo \x: U + 2029 è \x{2029} ma \x2029 è una spaziatura ASCII (U + 0020) + una cifra 2 + a cifre 9. \n all'esterno di una classe di caratteri, non è garantita anche per abbinare \x{0a}.

1

Se la piattaforma non supporta la classe \R come suggerito da @dawg cui sopra, si può ancora essere in grado di ottenere una soluzione piuttosto elegante e robusta se la piattaforma supporta negativo lookaround o classe di caratteri sottrazione (per esempio in Java classe di sottrazione è attraverso il syntax[x&&[^y]]).

Nella maggior parte delle grammatiche di espressioni regolari, il carattere punto è definito per indicare "qualsiasi carattere tranne il carattere di fine riga" (vedere ad esempio, per JavaScript, here). Se corrisponde a qualcosa con le seguenti caratteristiche:

  1. non (qualsiasi carattere eccetto il carattere di fine riga) → il carattere di nuova riga; e
  2. è spazio bianco

Dal Attualmente sto lavorando in JavaScript, che per quanto ne so non ha la classe di caratteri sottrazione \R stenografia o, posso ancora usare lookahead negativo per ottenere ciò che voglio. La seguente espressione regolare corrisponde a tutti i ritorni a capo:

/((?!.)\s)+/g 

E il seguente codice JavaScript, almeno quando eseguito in Chrome 42.0.2311.90m su Windows 7, spazza via tutti i tipi di nuove linee che JavaScript (vale a dire il "ECMAScript" di cui al terzo comma di @ dawg) riconosce:

var input = "hello\r\n\f\v\u2028\u2029 world"; 
 
var output = input.replace(/((?!.)\s)+/g, ""); 
 
document.write(output); // hello world