Ich habe Perl regulären Ausdruck mit Modifikator s m und g gelesen. Ich verstehe, dass // g eine globale Übereinstimmung ist, wo es eine gierige Suche sein wird.
Aber ich bin verwirrt mit den Modifier s und m. Kann jemand den Unterschied zwischen s und m anhand des Codebeispiels erläutern, um zu zeigen, wie es anders sein kann? Ich habe versucht, online zu suchen und es gibt nur Erklärung wie in dem Link Ссылка . Im Stackoverflow habe ich sogar Leute gesehen, die s und m zusammen benutzen. Ist nicht s das Gegenteil von m?
%Vor%Ich bin nicht in der Lage, mehrere Zeilen mit m zu verknüpfen.
%Vor% Die Dokumentation , die Sie mit sich selbst verlinken, scheint mir sehr klar zu sein. Es würde helfen, wenn Sie erklären würden, welches Problem Sie hatten, es zu verstehen, und wie Sie zu der Annahme kamen, dass /s
und /m
Gegensätze waren.
Kurz gesagt, /s
ändert das Verhalten des Dot-Metazeichens .
so, dass es mit einem beliebigen Zeichen übereinstimmt. Normalerweise entspricht es allem außer einer neuen Zeile "\n"
und behandelt die Zeichenfolge daher als eine s einzelne Zeile, selbst wenn sie Zeilenumbrüche enthält.
/m
ändert die Caret ^
und dollar $
Metazeichen so, dass sie an Zeilenumbrüchen innerhalb der Zeichenfolge zusammenpassen und sie als m ulti-line behandeln Zeichenfolge. Normalerweise werden sie nur am Anfang und Ende der Zeichenfolge übereinstimmen.
Sie sollten nicht verwirrt werden, wenn der Modifikator /g
"gierig" ist. Es ist für g lobale Übereinstimmungen, die alle Vorkommen des Musters innerhalb der Zeichenfolge finden. Der Begriff gierig ist normalerweise Benutzer für das Verhalten von Quantifizierern innerhalb des Musters. Zum Beispiel wird .*
als gierig bezeichnet, da es so viele Zeichen wie möglich enthält, im Gegensatz zu .*?
, das mit wenigen Zeichen übereinstimmt.
Aktualisieren
In Ihrer modifizierten Frage verwenden Sie /".*"/mg
, wobei /m
irrelevant ist, weil, wie oben erwähnt, dieser Modifizierer nur das Verhalten der Metazeichen metacaracter $
und ^
ändert, und es gibt keine in dein Muster.
Wenn Sie es in /".*"/sg
ändern, werden die Dinge ein wenig verbessert, da .
nun mit dem Zeilenumbruch am Ende jeder Zeile übereinstimmen kann und das Muster mit mehrzeiligen Strings übereinstimmen kann. (Beachten Sie, dass es sich hierbei um die Objekt Zeichenfolge handelt, die "einzelne Zeile" ist - dh die Übereinstimmung verhält sich genau so, als ob es keine Zeilenumbrüche in% gab co_de% ist betroffen.) Höher ist hier die konventionelle Bedeutung von greedy , weil das Muster jetzt vom ersten doppelten Zitat in der ersten Zeile bis zum letzten doppelten Zitat am Ende des letzten übereinstimmt Linie. Ich nehme an, das ist nicht was du willst.
Es gibt einige Möglichkeiten, dies zu beheben. Ich empfehle, das Muster so zu ändern, dass die gewünschte Zeichenfolge ein Anführungszeichen ist, gefolgt von einer beliebigen Zeichenfolge mit Ausnahme von Anführungszeichen , gefolgt von einem weiteren doppelten Anführungszeichen. Dies ist geschrieben .
(beachten Sie, dass der Modifikator /"[^"]*"/g
nicht mehr notwendig ist, da es jetzt keine Punkte im Muster gibt) und fast alles, was Sie wollen, außer dass die Escape-Anführungszeichen das Muster beenden.
Sehen Sie sich dieses Programm und seine Ausgabe an, und notiere mir, dass ich zu Beginn jedes Matches einen chevron /s
gesetzt habe, damit sie unterschieden werden können
Ausgabe
%Vor% Wie Sie sehen können, ist jetzt alles in Ordnung, außer dass in >>
zwei Übereinstimmungen gefunden wurden, "This is \"string\""
, und "This is \"
. Das zu beheben ist vielleicht komplizierter als Sie wollen, aber es ist durchaus möglich. Bitte sagen Sie es, wenn Sie das auch reparieren müssen.
Aktualisieren
Ich kann das genauso gut abschließen. Um die doppelten doppelten Anführungszeichen zu ignorieren und sie nur als Teil der Zeichenfolge zu behandeln, müssen wir entweder ""
oder jedes Zeichen außer Double-Quote akzeptieren. Dies geschieht mit dem Regex-Alternationsoperator \"
und muss in nicht-einfangenden Klammern |
gruppiert werden. Das Endergebnis ist (?: ... )
(der Backslash selbst muss maskiert sein, damit er verdoppelt wird), was, wenn er in das obige Programm eingefügt wird, diese Ausgabe erzeugt, von der ich annehme, dass sie das ist, was Sie wollten.
Mit /".*"/mg
deine Übereinstimmung
"
.*"
entspricht so viel wie möglich jedem Zeichen (außer \n
) bis "
/g
verwenden und die Übereinstimmung bei der zweiten "
gestoppt ist, wird regex versuchen, die ersten beiden Schritte zu wiederholen /m
macht hier keinen Unterschied, da Sie nicht ^
oder $
anchors Da Sie in Ihrem Beispiel keine Anführungszeichen verwendet haben, ist regex nicht das beste Werkzeug, um das zu tun, was Sie wollen.
Wenn das nicht der Fall ist und Sie möchten, dass alles zwischen zwei Anführungszeichen steht, übernimmt /".*?"/gs
die Aufgabe.
/m
und /s
beeinflussen beide, wie der Match-Operator mehrzeilige Strings behandelt.
Mit dem% -Modifizierer% co_de stimmen /m
und ^
mit dem Anfang und dem Ende jeder Zeile innerhalb der Zeichenfolge überein. Ohne den% modifier $
stimmen /m
und ^
nur mit dem Anfang und dem Ende der Zeichenfolge überein.
Beispiel:
%Vor% Mit dem Modifizierer $
stimmt das Sonderzeichen /s
mit allen Zeichen überein, einschließlich Zeilenumbrüchen. Ohne den% modifier .
stimmt /s
mit allen Zeichen überein, mit Ausnahme von Zeilenumbrüchen.
Es ist möglich, .
Modifikatoren zusammen zu verwenden.
Borodins Regex wird für die Beispiele aus dieser Laboraufgabe funktionieren.
Es ist jedoch auch möglich, dass ein Backslash sich selbst entkommt. Dies tritt auf, wenn man Windows-Pfade in eine Zeichenfolge einbezieht, so dass die folgende Regex diesen Fall erfassen würde:
%Vor%Ausgaben:
%Vor%Für eine schnelle Erklärung des Musters:
%Vor%