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, MULTILINEnie 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 $. DOTALLtryb 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.