Regex passend zu EOF

89

Ich habe einige Daten, die so aussehen

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

Ich verwende diesen regulären Ausdruck, um die Namen abzugleichen

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

Dies funktioniert größtenteils, aber die Datei endet abrupt nach dem letzten Wort, was bedeutet, dass der letzte Wert nicht \r\nmit \noder ,mit EOF endet. Gibt es eine Möglichkeit, EOF in Regex abzugleichen, damit ich es in dieser zweiten Gruppierung korrigieren kann?

Ryan
quelle
Versuchen Sie, alle Namen in einer Gruppe oder einer Erfassungsgruppe pro Name zu erfassen?
Andrew Hare
Eine Sache, die Sie tun müssen, wenn Sie Probleme mit Regex haben, ist, Elemente Ihres Musters isoliert auszuprobieren. Wenn Sie am Ende über das Token besorgt sind, testen Sie Ihren Ausdruck ohne es.
Akf
wollte nur eine große regex Test Site hinzuzufügen: regexplanet.com/simple
Nordpol
@ Sinan - ich stimme zu; fusioniert
Marc Gravell

Antworten:

159

Die Antwort auf diese Frage \Zhat eine Weile gedauert, bis ich sie herausgefunden habe, aber sie funktioniert jetzt. Beachten Sie, dass umgekehrt der \AAnfang der gesamten Zeichenfolge übereinstimmt (im Gegensatz zu ^und $am Anfang einer Zeile).

Ryan
quelle
5
Nur ein Hinweis, wenn Sie nach einer solchen Funktion in Netbeans für eine Projektdateisuche im Gegensatz zu einer In-Datei-Suche suchen , wird sich das Folgende anders verhalten ... (\s*)\?>(\s*)\Z... und nach einigem weiteren Graben hier ist, was in einem Projektordner funktionieren würde : (\s*)\?>(\s*)(\n*)(\W)\Z FYI: Dies dient dazu, alle schließenden PHP-Tags durch Zeilenumbrüche am Ende der Datei zu ersetzen.
MediaVince
1
Es stellt sich heraus, \Afunktioniert auch in Visual Studio suchen und ersetzen. Verwenden Sie solche Dinge wie immer mit Vorsicht, aber es ersparte mir eine Menge manuelles Durcheinander, sobald ich froh war, dass es tatsächlich das Richtige tun würde.
Steve Pettifer
Während ich Javas ScannerKlasse benutze , um eine ganze Datei auf einmal zu lesen; Wenn ich \Zals Trennzeichen verwende, wird das nachfolgende Zeilenumbruchzeichen abgeschnitten. Wenn ich das Trennzeichen in geändert habe \z, bleibt das nachgestellte Zeilenumbruchzeichen erhalten. Es scheint, dass Martin Doreys Antwort auch für Java gilt.
mmdemirbas
24

EOF ist eigentlich kein Charakter. Wenn Sie eine mehrzeilige Zeichenfolge haben, stimmt '$' sowohl mit dem Ende der Zeichenfolge als auch mit dem Ende einer Zeile überein.

In Perl und seinen Brüdern, \Aund \Zpassen Sie den Anfang und das Ende der Zeichenfolge an, wobei Sie Zeilenumbrüche völlig ignorieren.

GNU-Erweiterungen für POSIX-Regexes verwenden \`und \'für die gleichen Dinge.

paxdiablo
quelle
17

In Visual Studio finden Sie EOF wie folgt : $(?![\r\n]). Dies funktioniert unabhängig davon, ob Ihre Zeilenenden CR, CRLF oder nur LF sind.

Als Bonus können Sie sicherstellen, dass alle Ihre Codedateien einen endgültigen Zeilenumbruch haben:

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

So funktioniert das:

Suchen Sie ein Zeilenende (eine Übereinstimmung mit der Breite Null), dem weder CR noch LF vorangestellt sind und dem auch CR oder LF nicht folgen. Einige Gedanken werden Ihnen zeigen, warum dies funktioniert!

Beachten Sie, dass Sie durch Ihr gewünschtes Zeilenendezeichen ersetzen sollten, sei es CR, LF oder CRLF.

ErikE
quelle
In Visual Studio 2019 gibt es einen Fehler, bei dem das Ersetzen aller Elemente dazu führen kann, dass am Ende der Datei zwei neue Zeilen hinzugefügt werden. Ich denke, es hat etwas mit der Option zum automatischen Einfügen von Zeilenumbrüchen beim Speichern zu tun.
Stevoisiak
9

Vergleichen Sie das Verhalten von Ryans vorgeschlagenem \ Z mit \ z:

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

perlre sez:

\ Z Nur am Ende der Zeichenfolge oder vor dem Zeilenumbruch am Ende übereinstimmen
\ z Nur am Ende der Zeichenfolge übereinstimmen

Eine Übersetzung des Testfalls in Ruby (1.8.7, 1.9.2) verhält sich genauso.

Martin Dorey
quelle
3

Müssen Sie wirklich die Zeilentrennzeichen erfassen? Wenn nicht, sollte dieser reguläre Ausdruck alles sein, was Sie brauchen:

/\w+/

Dies setzt voraus, dass alle Teilzeichenfolgen, die Sie abgleichen möchten, wie in Ihrem Beispiel vollständig aus Wortzeichen bestehen.

Alan Moore
quelle
2

Vielleicht versuchen Sie $ (EOL / EOF) anstelle von (\ r \ n | \ n)?

/\"(.+?)\".+?(\w.+?)$/
Marc Gravell
quelle
2

Vor kurzem habe ich nach so etwas gesucht, aber nach JavaScript.

Stellen Sie dies hier ein, damit jeder mit dem gleichen Problem davon profitieren kann

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

Grundsätzlich würde dies mit dem Zeilenende übereinstimmen, auf das kein Wagenrücklauf oder neue Zeilenzeichen folgen. Im Wesentlichen ist dies dasselbe wie \Zfür JavaScript.

Zlatin Zlatev
quelle
1

Angenommen, Sie verwenden den richtigen Modifikator, um die Zeichenfolge als Ganzes zu behandeln (nicht zeilenweise - und wenn \ n für Sie funktioniert, verwenden Sie sie), fügen Sie einfach eine weitere Alternative hinzu - Ende der Zeichenfolge: (\ r \ n | \ n |, | $)

Blattknoten
quelle
0

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

Würfel
quelle
5
Wahrscheinlich. Ich erinnere mich nicht mehr :-)
Würfel