Це не має нічого спільного з прапором MULTILINE; що ви бачите, це різниця між методами find()та matches(). find()успішно, якщо відповідність можна знайти в будь-якому місці цільового рядка , тоді як matches()очікує, що регулярний вираз відповідає всій рядку .
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
Крім того, MULTILINEне означає, що ви думаєте, що це робить. Здається, багато людей приходять до висновку, що вам потрібно використовувати цей прапор, якщо ваша цільова рядок містить нові рядки - тобто якщо він містить кілька логічних рядків. Я бачив тут декілька відповідей на SO щодо цього ефекту, але насправді все, що прапор робить, - це зміни поведінки якорів, ^і $.
Зазвичай ^відповідає самому початку цільового рядка і $відповідає самому кінці (або перед новим рядком наприкінці, але ми покинемо це осторонь). Але якщо рядок містить нові рядки, ви можете вибрати ^та $відповідати на початку та в кінці будь-якого логічного рядка, а не лише початку та кінця всього рядка, встановивши прапор MULTILINE.
Тож забудьте про те, що MULTILINE означає, і просто пам’ятайте, що це робить : змінює поведінку ^та $прив’язки. DOTALLСпочатку режим називався "однолінійним" (і досі він є в деяких ароматах, включаючи Perl і .NET), і він завжди викликав подібну плутанину. Нам пощастило, що Java-розробники пішли з більш описовою назвою в цьому випадку, але розумної альтернативи режиму "багаторядковий" не було.
У Перлі, де почалося все це божевілля, вони визнали свою помилку і позбулися як «багатолінійного», так і «однолінійного» режимів у регексах Perl 6. Ще через двадцять років, можливо, решта світу піде за цим прикладом.