Isso não tem nada a ver com a bandeira MULTILINE; o que você está vendo é a diferença entre os métodos find()
e matches()
. find()
terá êxito se uma correspondência puder ser encontrada em qualquer lugar da sequência de destino , enquanto matches()
espera que o regex corresponda à sequência inteira .
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
Além disso, MULTILINE
não significa o que você pensa que faz. Muitas pessoas parecem chegar à conclusão de que você precisa usar esse sinalizador se a sequência de destino contiver novas linhas - ou seja, se contiver várias linhas lógicas. Eu já vi várias respostas aqui no SO para esse efeito, mas, na verdade, tudo o que a flag faz é alterar o comportamento das âncoras ^
e $
.
Normalmente ^
corresponde ao início da string de destino e $
corresponde ao final (ou antes de uma nova linha no final, mas vamos deixar isso de lado por enquanto). Mas se a sequência contiver novas linhas, você poderá escolher ^
e $
corresponder no início e no final de qualquer linha lógica, não apenas no início e no final de toda a sequência, configurando o sinalizador MULTILINE.
Portanto, esqueça o que MULTILINE
significa e lembre-se do que ele faz : altera o comportamento das âncoras ^
e $
. DOTALL
O modo foi originalmente chamado de "linha única" (e ainda existe em alguns tipos, incluindo Perl e .NET), e sempre causou confusão semelhante. Temos a sorte de que os desenvolvedores Java tenham o nome mais descritivo nesse caso, mas não havia alternativa razoável para o modo "multilinha".
No Perl, onde toda essa loucura começou, eles admitiram seu erro e se livraram dos modos "multilinha" e "linha única" nas expressões regulares do Perl 6. Em outros vinte anos, talvez o resto do mundo tenha seguido o exemplo.