Nie ma to nic wspólnego z flagą MULTILINE; to, co widzisz, to różnica między metodami find()
i matches()
. find()
powiedzie się, jeśli dopasowanie można znaleźć w dowolnym miejscu w ciągu docelowym , podczas gdy matches()
oczekuje, że wyrażenie regularne będzie pasować do całego ciągu .
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
Co więcej, MULTILINE
nie oznacza tego, co myślisz, że robi. Wiele osób wydaje się dochodzić do wniosku, że musisz użyć tej flagi, jeśli twój docelowy ciąg zawiera znaki nowej linii - to znaczy, jeśli zawiera wiele linii logicznych. Widziałem tutaj kilka odpowiedzi na SO w tym celu, ale w rzeczywistości wszystko, co robi ta flaga, to zmienia zachowanie kotwic, ^
i $
.
Zwykle ^
dopasowuje sam początek ciągu docelowego i $
dopasowuje sam koniec (lub przed nową linią na końcu, ale na razie zostawimy to na boku). Ale jeśli ciąg zawiera znaki nowej linii, możesz wybrać opcję ^
i $
dopasować na początku i na końcu dowolnej linii logicznej, a nie tylko na początku i na końcu całego ciągu, ustawiając flagę MULTILINE.
Więc zapomnij o tym, co MULTILINE
oznacza i po prostu pamiętaj, co robi : zmienia zachowanie kotwic ^
i $
. DOTALL
tryb początkowo był nazywany „jednoliniowym” (i nadal występuje w niektórych wersjach, w tym w Perlu i .NET) i zawsze powodował podobne zamieszanie. Na szczęście twórcy Javy wybrali w tym przypadku bardziej opisową nazwę, ale nie było rozsądnej alternatywy dla trybu „wielowierszowego”.
W Perlu, gdzie całe to szaleństwo się zaczęło, przyznali się do błędu i pozbyli się trybu „wielowierszowego” i „pojedynczej linii” w wyrażeniach regularnych Perl 6. Za dwadzieścia lat może reszta świata pójdzie w ich ślady.