Das hat nichts mit der MULTILINE-Flagge zu tun; Was Sie sehen, ist der Unterschied zwischen den find()
und matches()
Methoden. find()
erfolgreich, wenn eine Übereinstimmung irgendwo in der Zielzeichenfolge gefunden werden kann, während matches()
erwartet, dass die Regex die gesamte Zeichenfolge entspricht.
Pattern p = Pattern.compile("xyz");
Matcher m = p.matcher("123xyzabc");
System.out.println(m.find()); // true
System.out.println(m.matches()); // false
Matcher m = p.matcher("xyz");
System.out.println(m.matches()); // true
Außerdem MULTILINE
bedeutet nicht, was Sie denken, es tut. Viele Leute scheinen zu der Schlussfolgerung zu gelangen, dass Sie dieses Flag verwenden müssen, wenn Ihre Zielzeichenfolge Zeilenumbrüche enthält - dh wenn sie mehrere logische Zeilen enthalten. Ich habe mehrere Antworten hier auf SO zu diesem Zweck gesehen, aber in der Tat ändert dieses Flag das Verhalten der Anker, ^
und $
.
Normalerweise entspricht ^
dem Anfang der Zielzeichenfolge, und $
entspricht dem Ende (oder vor einem Zeilenende am Ende, aber wir lassen das für jetzt beiseite). Wenn die Zeichenfolge jedoch Zeilenumbrüche enthält, können Sie für ^
und $
auswählen, dass sie am Anfang und am Ende jeder logischen Zeile und nicht nur am Anfang und Ende der gesamten Zeichenfolge durch Setzen des MULTILINE-Flags übereinstimmen.
So etwa vergessen, was MULTILINE
bedeutet und nur daran erinnern, was es tut: das Verhalten des ^
und $
Ankers ändert. DOTALL
Modus wurde ursprünglich "Single-Line" (und ist immer noch in einigen Geschmacksrichtungen, einschließlich Perl und .NET), und es hat immer eine ähnliche Verwirrung verursacht. Wir haben Glück, dass die Java-Entwickler in diesem Fall mit dem besser beschreibenden Namen gingen, aber es gab keine vernünftige Alternative für den "Multiline" -Modus.
In Perl, wo all dieser Wahnsinn begann, haben sie ihren Fehler zugegeben und sowohl "Multiline" - als auch "Single-Line" -Modi in Perl 6 Regexes losgeworden. In weiteren zwanzig Jahren wird vielleicht der Rest der Welt ihm gefolgt sein.
Ich versuche ein Muster zu finden, das zu jeder Zeichenfolge passt, die mit beginnt "Benutzerkommentare:" Nach diesem "User Comments:" gibt ein Benutzer ein Textfeld ein und kann daher * alles * - sogar neue Zeilen enthalten. Sieht so aus, als müsste ich viel in Regex lernen ... – Nivas
Das funktioniert (danke!) Ich habe das Muster '(? S) User Comments: \ s * (. *)' Versucht. Aus der Antwort von @Amarghosh habe ich das Muster 'User Comments: [\\ s \\ S] *'. Unter diesen gibt es einen * besseren * oder * empfohlenen * Weg oder sind dies nur zwei verschiedene Möglichkeiten, das gleiche zu tun? – Nivas
Sie beide gleich; '[\ s \ S]' ist etwas expliziter ("setze ein beliebiges Zeichen, das entweder Leerzeichen oder Nicht-Leerzeichen ist"), '.' ist einfacher zu lesen, aber du musst nach dem' (? s) 'suchen oder 'DOTALL', um herauszufinden, ob Zeilenumbrüche enthalten sind oder nicht. Ich bevorzuge '.' mit dem' Pattern.DOTALL' Flag Set (das ist meiner Meinung nach leichter zu lesen und zu erinnern als '(? S)'. Sie sollten das verwenden, womit Sie sich am wohlsten fühlen. –