W3docs

Flag Regex in Java

Modifica il comportamento delle regex Java con i flag — CASE_INSENSITIVE, MULTILINE, DOTALL, COMMENTS e la sintassi inline (?i).

Un flag cambia il modo in cui un'espressione regolare viene interpretata senza modificare il pattern stesso. La stessa espressione può trovare corrispondenze con o senza distinzione tra maiuscole e minuscole, trattare una stringa come una singola riga o come più righe, e lasciare che . attraversi le interruzioni di riga oppure si fermi ad esse — tutto deciso dai flag. In Java puoi impostarli in due modi: come costanti int passate a Pattern.compile(pattern, flags), oppure come switch inline in stile (?i) scritti all'interno del pattern. Questo capitolo tratta i flag che usi quotidianamente e come combinarli.

I due modi per impostare un flag

Ogni flag ha una costante nella classe Pattern. Passala come secondo argomento a compile:

Pattern p = Pattern.compile("error", Pattern.CASE_INSENSITIVE);

Lo stesso comportamento è disponibile all'interno del pattern come modificatore inline, così una regex semplice può portare i propri flag senza un secondo argomento:

Pattern p = Pattern.compile("(?i)error");          // whole pattern, case-insensitive
Pattern q = Pattern.compile("(?i:error) CODE");    // only the group is case-insensitive

I flag inline sono utili quando il pattern viene trasportato come stringa semplice — un file di configurazione, una colonna di database, un'annotazione — dove non puoi anche passare un int. La forma con costante è più chiara quando il flag fa parte del tuo codice.

I flag che userai davvero

CostanteInlineEffetto
CASE_INSENSITIVE(?i)Trova corrispondenze con le lettere ASCII indipendentemente dal caso
MULTILINE(?m)^ e $ corrispondono a ogni confine di riga, non solo agli estremi della stringa
DOTALL(?s). corrisponde anche ai terminatori di riga (s = "single line")
COMMENTS(?x)Ignora gli spazi non escapati e tratta # come un commento
UNICODE_CASE(?u)Fa sì che CASE_INSENSITIVE gestisca le lettere Unicode, non solo ASCII
UNICODE_CHARACTER_CLASS(?U)Fa sì che \w, \d, \b seguano le regole Unicode
LITERALTratta l'intero pattern come testo semplice, senza metacaratteri

Una sorpresa comune: CASE_INSENSITIVE da solo gestisce solo l'ASCII. Per trovare corrispondenze con lettere accentate o non latine senza distinzione tra maiuscole e minuscole, combinalo con UNICODE_CASE.

Insensibilità al caso

Per impostazione predefinita una regex è sensibile al caso, quindi error non corrisponde a ERROR. Aggiungendo CASE_INSENSITIVE entrambi trovano corrispondenza:

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

Gestione delle righe: MULTILINE e DOTALL

Questi due sono indipendenti e spesso confusi. MULTILINE cambia gli ancoraggi ^ e $; DOTALL cambia il punto ..

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

Usa MULTILINE quando analizzi testo multi-riga di log o documenti riga per riga, e DOTALL quando una singola corrispondenza deve estendersi su più righe (un blocco HTML, un record multi-riga).

Combinare i flag

Le costanti dei flag sono maschere di bit, quindi le combini con l'operatore OR bit a bit |:

int flags = Pattern.MULTILINE | Pattern.CASE_INSENSITIVE | Pattern.DOTALL;
Pattern p = Pattern.compile("^error.*done$", flags);

L'equivalente inline impila le lettere: (?ims) imposta tutti e tre. Puoi anche disattivare un flag all'interno di un gruppo con un meno: (?-i) disabilita l'insensibilità al caso per il resto del pattern.

Pattern leggibili con COMMENTS

Il flag COMMENTS (inline (?x)) permette a un pattern complesso di respirare: gli spazi non escapati vengono ignorati e # inizia un commento fino a fine riga. Questo trasforma un'indecifrabile riga unica in qualcosa che puoi mantenere:

Pattern phone = Pattern.compile("""
    \\d{3}   # area code
    -        # separator
    \\d{4}   # line number
    """, Pattern.COMMENTS);
phone.matcher("555-1234").matches();   // true

Poiché gli spazi reali vengono ignorati, per trovare uno spazio letterale usa \\s, \\ , o una classe di caratteri come [ ].

Un esempio pratico: un'espressione, molti flag

Questo programma esegue la stessa manciata di pattern con e senza flag in modo da poter vedere ogni flag che cambia il risultato. Conta le corrispondenze senza distinzione tra maiuscole e minuscole, ancora le righe con MULTILINE, attraversa le interruzioni di riga con DOTALL, combina i flag con |, e usa sia switch inline globali che con scope.

java— editable, runs on the server

Cosa ricavare dall'esecuzione:

  • CASE_INSENSITIVE ha trovato 2 occorrenze di error (la ERROR maiuscola e la error minuscola) mentre il pattern predefinito ne ha trovata solo 1 — la prova che la sensibilità al caso è attiva a meno che non si richieda il flag.
  • MULTILINE ha fatto corrispondere ^error:.*$ alla riga centrale del log e ha stampato error: timeout; senza il flag, ^ e $ ancorano solo agli estremi dell'intera stringa, quindi quella riga interna non corrisponderebbe mai.
  • DOTALL ha permesso a warn.*info di saltare attraverso le due interruzioni di riga incorporate e trovare corrispondenza (true), mentre lo stesso pattern senza il flag ha restituito false perché . si ferma a un terminatore di riga per impostazione predefinita.
  • Il pattern combinato MULTILINE | CASE_INSENSITIVE ha trovato corrispondenza per ^ERROR in una riga che inizia effettivamente con error: minuscolo — true conferma che entrambi i flag erano applicati contemporaneamente da una singola maschera OR bit a bit.
  • Il pattern con scope (?i:hello) WORLD ha trovato corrispondenza con HELLO WORLD (true) ma non con HELLO world (false): il gruppo (?i:...) ha gestito il caso solo per hello, lasciando il WORLD finale rigorosamente sensibile al caso — esattamente la precisione che lo scoping inline offre.

Argomenti correlati

Esercitazione

Pratica
Compili un pattern con Pattern.compile('first.*second', Pattern.MULTILINE) e lo confronti con il testo 'first line\nsecond line'. Perché non trova corrispondenza e quale flag risolverebbe il problema?
Compili un pattern con Pattern.compile('first.*second', Pattern.MULTILINE) e lo confronti con il testo 'first line\nsecond line'. Perché non trova corrispondenza e quale flag risolverebbe il problema?
Was this page helpful?