regex per abbinare EOF


92

Ho alcuni dati che assomigliano a questo

john, dave, chris
rick, sam, bob
joe, milt, paul

Sto usando questa regex per abbinare i nomi

/(\w.+?)(\r\n|\n|,)/

che funziona per la maggior parte ma il file termina bruscamente dopo l'ultima parola, il che significa che l'ultimo valore non finisce con \r\n, \no ,finisce con EOF. C'è un modo per abbinare EOF in regex in modo da poterlo inserire nel secondo raggruppamento?


Stai cercando di catturare tutti i nomi in un gruppo o un gruppo di cattura per nome?
Andrew Hare

una cosa da fare quando si hanno problemi con le espressioni regolari è provare gli elementi del proprio pattern in isolamento. se sei preoccupato per il token alla fine, prova la tua espressione senza di esso.
akf

volevo solo aggiungere un ottimo sito di test regex: regexplanet.com/simple
northpole


@ Sinan - Sono d'accordo; fusa
Marc Gravell

Risposte:


163

La risposta a questa domanda \Zmi ci è voluto un po 'per capirla, ma ora funziona. Si noti che, al contrario, \Acorrisponde all'inizio dell'intera stringa (al contrario ^e alla $corrispondenza dell'inizio di una riga).


5
Solo un avvertimento se stai cercando tale funzionalità in netbeans per una ricerca di file di progetto rispetto a una ricerca di file , quanto segue si comporterà in modo diverso ... (\s*)\?>(\s*)\Z... e dopo un po 'di ricerca ecco cosa funzionerebbe su una cartella di progetto : (\s*)\?>(\s*)(\n*)(\W)\Z FYI: questo serve a sostituire tutti i tag php di chiusura con interruzioni di riga alla fine del file.
MediaVince

1
Si scopre che \Afunziona anche in Visual Studio trova e sostituisci. Come sempre usa queste cose con cautela, ma mi ha risparmiato un sacco di problemi manuali una volta che ero felice che avrebbe effettivamente fatto la cosa giusta.
Steve Pettifer

Mentre sto usando la Scannerclasse Java per leggere un intero file in una volta; se uso \Zcome delimitatore, il carattere di nuova riga finale viene tagliato. Quando ho cambiato delimitatore in \z, il carattere di nuova riga finale è stato conservato. Sembra che la risposta di Martin Dorey valga anche per Java.
mmdemirbas

24

EOF non è in realtà un personaggio. Se hai una stringa su più righe, "$" corrisponderà sia alla fine della stringa che alla fine di una riga.

In Perl e nei suoi fratelli, \Ae \Zabbina l'inizio e la fine della stringa, ignorando totalmente le interruzioni di riga.

Le estensioni GNU alle espressioni regolari POSIX usano \`e \'per le stesse cose.


18

In Visual Studio, è possibile trovare EOF in questo modo: $(?![\r\n]). Funziona sia che le terminazioni di riga siano CR, CRLF o solo LF.

Come bonus, puoi assicurarti che tutti i tuoi file di codice abbiano un marcatore di nuova riga finale in questo modo:

               Find What: (?<![\r\n])$(?![\r\n])
            Replace With: \r\n
 Use Regular Expressions: checked
Look at these file types: *.cs, *.cshtml, *.js

Come funziona:

Trova qualsiasi fine di riga (una corrispondenza di larghezza zero) che non sia preceduta da CR o LF e non sia seguita da CR o LF. Qualche pensiero ti mostrerà perché funziona!

Nota che dovresti sostituire con il carattere di fine riga desiderato, sia esso CR, LF o CRLF.


C'è un bug in Visual Studio 2019 in cui eseguire una sostituzione di tutto con questo può comportare l'aggiunta di due nuove righe alla fine del file. Penso che abbia qualcosa a che fare con l'opzione di inserimento automatico della nuova riga al salvataggio.
Stevoisiak

10

Confronta il comportamento della \ Z suggerita da Ryan con \ z:

$ perl -we 'my $ corpus = "ciao \ n"; $ corpus = ~ s / \ Z / world / g; print (": $ corpus: \ n") '
:Ciao mondo
mondo:
$ perl -we 'my $ corpus = "ciao \ n"; $ corpus = ~ s / \ z / world / g; print (": $ corpus: \ n") '
:Ciao
mondo:
$ 

perlre sez:

\ Z Corrisponde solo alla fine della stringa o prima della nuova riga alla fine
\ z Corrisponde solo alla fine della stringa

Una traduzione del test case in Ruby (1.8.7, 1.9.2) si comporta allo stesso modo.


4

Recentemente stavo cercando qualcosa di simile, ma per JavaScript.

Mettendolo qui, in modo che chiunque abbia lo stesso problema possa trarne vantaggio

var matchEndOfInput = /$(?![\r\n])/gm;

Fondamentalmente questo corrisponderebbe alla fine della riga, che non è seguita da un ritorno a capo o da nuovi caratteri di riga. In sostanza questo è lo stesso \Zma per JavaScript.


2

Devi davvero catturare i separatori di riga? In caso contrario, questa regex dovrebbe essere tutto ciò di cui hai bisogno:

/\w+/

Ciò presuppone che tutte le sottostringhe che desideri trovare siano costituite interamente da caratteri alfanumerici, come nel tuo esempio.


2

Forse provare $ (EOL / EOF) invece di (\ r \ n | \ n)?

/\"(.+?)\".+?(\w.+?)$/

1

Supponendo che tu stia usando un modificatore appropriato che costringe a trattare la stringa nel suo insieme (non riga per riga - e se \ n funziona per te, lo stai usando), aggiungi semplicemente un'altra alternativa - fine della stringa: (\ r \ n | \ n |, | $)


0

/(\w.+?)(\r\n|\n|,|$)/


5
Probabilmente. Non ricordo più :-)
cubo
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.