Flags de Regex em Java
Modifique o comportamento do regex Java com flags — CASE_INSENSITIVE, MULTILINE, DOTALL, COMMENTS e a sintaxe inline (?i).
Uma flag altera a forma como uma expressão regular é interpretada sem modificar o próprio padrão. A mesma expressão pode corresponder com ou sem distinção entre maiúsculas e minúsculas, tratar uma string como uma linha única ou múltiplas, e permitir que . cruze quebras de linha ou pare nelas — tudo decidido por flags. Em Java, você as define de duas maneiras: como constantes int passadas para Pattern.compile(pattern, flags), ou como modificadores inline no estilo (?i) escritos dentro do padrão. Este capítulo cobre as flags que você usa no dia a dia e como combiná-las.
As duas formas de definir uma flag
Cada flag possui uma constante na classe Pattern. Passe-a como segundo argumento para compile:
Pattern p = Pattern.compile("error", Pattern.CASE_INSENSITIVE);O mesmo comportamento está disponível dentro do padrão como modificador inline, para que uma string regex simples possa carregar suas próprias flags sem segundo argumento:
Pattern p = Pattern.compile("(?i)error"); // whole pattern, case-insensitive
Pattern q = Pattern.compile("(?i:error) CODE"); // only the group is case-insensitiveFlags inline são úteis quando o padrão é passado como uma string simples — um arquivo de configuração, uma coluna de banco de dados, uma anotação — onde não é possível passar também um int. A forma constante é mais clara quando a flag faz parte do seu código.
As flags que você realmente vai usar
| Constante | Inline | Efeito |
|---|---|---|
CASE_INSENSITIVE | (?i) | Corresponde letras ASCII independentemente de maiúsculas/minúsculas |
MULTILINE | (?m) | ^ e $ correspondem em cada limite de linha, não apenas no início e fim da string |
DOTALL | (?s) | . também corresponde a terminadores de linha (s = "single line") |
COMMENTS | (?x) | Ignora espaços em branco não escapados e trata # como comentário |
UNICODE_CASE | (?u) | Faz CASE_INSENSITIVE dobrar letras Unicode, não apenas ASCII |
UNICODE_CHARACTER_CLASS | (?U) | Faz \w, \d, \b seguirem regras Unicode |
LITERAL | — | Trata todo o padrão como texto simples, sem metacaracteres |
Uma surpresa comum: CASE_INSENSITIVE sozinho dobra apenas ASCII. Para corresponder letras acentuadas ou não latinas sem distinção de maiúsculas/minúsculas, combine-o com UNICODE_CASE.
Insensibilidade a maiúsculas/minúsculas
Por padrão, um regex diferencia maiúsculas de minúsculas, então error não corresponde a ERROR. Adicione CASE_INSENSITIVE e ambos correspondem:
Pattern.compile("error").matcher("ERROR").find(); // false
Pattern.compile("error", Pattern.CASE_INSENSITIVE).matcher("ERROR").find(); // true
// For non-ASCII letters, add UNICODE_CASE:
Pattern.compile("é", Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE)
.matcher("É").find(); // trueTratamento de linhas: MULTILINE e DOTALL
Essas duas são independentes e frequentemente confundidas. MULTILINE altera as âncoras ^ e $; DOTALL altera o ponto ..
String text = "first line\nsecond line";
// Without MULTILINE, ^ matches only the very start of the input.
Pattern.compile("^second").matcher(text).find(); // false
// With MULTILINE, ^ matches the start of every line.
Pattern.compile("^second", Pattern.MULTILINE).matcher(text).find(); // true
// Without DOTALL, . will not cross the newline.
Pattern.compile("first.*second").matcher(text).find(); // false
// With DOTALL, . matches the newline too.
Pattern.compile("first.*second", Pattern.DOTALL).matcher(text).find(); // trueUse MULTILINE ao percorrer texto de log ou documento com múltiplas linhas, e DOTALL quando uma única correspondência precisa abranger várias linhas (um bloco HTML, um registro de múltiplas linhas).
Combinando flags
As constantes de flag são máscaras de bits, então você as combina com o operador OR bit a bit |:
int flags = Pattern.MULTILINE | Pattern.CASE_INSENSITIVE | Pattern.DOTALL;
Pattern p = Pattern.compile("^error.*done$", flags);O equivalente inline empilha as letras: (?ims) define as três ao mesmo tempo. Você também pode desativar uma flag dentro de um grupo com um sinal de menos: (?-i) desativa a insensibilidade a maiúsculas/minúsculas para o restante do padrão.
Padrões legíveis com COMMENTS
A flag COMMENTS (inline (?x)) permite que um padrão complexo respire: espaços em branco não escapados são ignorados e # inicia um comentário até o final da linha. Isso transforma um único liner ilegível em algo que você pode manter:
Pattern phone = Pattern.compile("""
\\d{3} # area code
- # separator
\\d{4} # line number
""", Pattern.COMMENTS);
phone.matcher("555-1234").matches(); // trueComo espaços em branco reais são ignorados, use \\s, \\ ou uma classe de caracteres como [ ] para corresponder a um espaço literal.
Um exemplo prático: uma expressão, várias flags
Este programa executa o mesmo conjunto de padrões com e sem flags para que você possa ver cada flag alterar o resultado. Ele conta correspondências sem distinção de maiúsculas/minúsculas, ancora linhas com MULTILINE, abrange quebras de linha com DOTALL, combina flags com | e usa modificadores inline globais e com escopo.
O que observar na execução:
CASE_INSENSITIVEencontrou 2 ocorrências deerror(oERRORem maiúsculas e oerrorem minúsculas), enquanto o padrão padrão encontrou apenas 1 — prova de que a sensibilidade a maiúsculas/minúsculas está ativa a menos que você solicite a flag.MULTILINEfez^error:.*$corresponder à linha do meio do log e imprimirerror: timeout; sem a flag,^e$ancoravam apenas às extremidades de toda a string, portanto, aquela linha interior nunca corresponderia.DOTALLpermitiu quewarn.*infosaltasse as duas quebras de linha incorporadas e correspondesse (true), enquanto o mesmo padrão sem a flag retornoufalseporque.para em um terminador de linha por padrão.- O padrão combinado
MULTILINE | CASE_INSENSITIVEcorrespondeu^ERRORa uma linha que realmente começa comerror:em minúsculas —trueconfirma que ambas as flags foram aplicadas ao mesmo tempo a partir de uma única máscara OR bit a bit. - O
(?i:hello) WORLDcom escopo correspondeu aHELLO WORLD(true) mas não aHELLO world(false): o grupo(?i:...)dobrou maiúsculas/minúsculas apenas parahello, deixando oWORLDfinal estritamente sensível a maiúsculas/minúsculas — exatamente a precisão que o escopo inline oferece.
Tópicos relacionados
- Expressões Regulares em Java — Introdução — como
PatterneMatcherse encaixam. - Pattern e Matcher — as classes que consomem as flags acima.
- Sintaxe de Regex e Classes de Caracteres — os metacaracteres que as flags modificam.
- Quantificadores e Grupos — onde flags inline com escopo como
(?i:...)são mais úteis.