Це не має нічого спільного з прапором 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. Ще через двадцять років, можливо, решта світу піде за цим прикладом.