W3docs

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-insensitive

Flags 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

ConstanteInlineEfeito
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
LITERALTrata 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();                                           // true

Tratamento 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(); // true

Use 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();   // true

Como 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.

java— editable, runs on the server

O que observar na execução:

  • CASE_INSENSITIVE encontrou 2 ocorrências de error (o ERROR em maiúsculas e o error em 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.
  • MULTILINE fez ^error:.*$ corresponder à linha do meio do log e imprimir error: timeout; sem a flag, ^ e $ ancoravam apenas às extremidades de toda a string, portanto, aquela linha interior nunca corresponderia.
  • DOTALL permitiu que warn.*info saltasse as duas quebras de linha incorporadas e correspondesse (true), enquanto o mesmo padrão sem a flag retornou false porque . para em um terminador de linha por padrão.
  • O padrão combinado MULTILINE | CASE_INSENSITIVE correspondeu ^ERROR a uma linha que realmente começa com error: em minúsculas — true confirma que ambas as flags foram aplicadas ao mesmo tempo a partir de uma única máscara OR bit a bit.
  • O (?i:hello) WORLD com escopo correspondeu a HELLO WORLD (true) mas não a HELLO world (false): o grupo (?i:...) dobrou maiúsculas/minúsculas apenas para hello, deixando o WORLD final estritamente sensível a maiúsculas/minúsculas — exatamente a precisão que o escopo inline oferece.

Tópicos relacionados

Prática

Prática
Você compila um padrão com Pattern.compile('first.*second', Pattern.MULTILINE) e o aplica ao texto 'first line\nsecond line'. Por que ele não encontra correspondência e qual flag resolveria o problema?
Você compila um padrão com Pattern.compile('first.*second', Pattern.MULTILINE) e o aplica ao texto 'first line\nsecond line'. Por que ele não encontra correspondência e qual flag resolveria o problema?
Was this page helpful?