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, MULTILINEnã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 $. DOTALLO 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.