Это не имеет ничего общего с флагом 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, где все это безумие началось, они признали свою ошибку и избавились от «многострочного» и «однострочного» режимов в регулярных выражениях Perl 6. Возможно, через двадцать лет остальной мир последует их примеру.