Flags de Regex en Java
Modifica el comportamiento de regex en Java con flags — CASE_INSENSITIVE, MULTILINE, DOTALL, COMMENTS y la sintaxis inline (?i).
Un flag cambia la forma en que se interpreta una expresión regular sin tocar el patrón en sí. La misma expresión puede coincidir con o sin distinción de mayúsculas y minúsculas, tratar una cadena como una sola línea o como varias, y permitir que . cruce saltos de línea o se detenga en ellos — todo decidido por los flags. En Java se configuran de dos maneras: como constantes int pasadas a Pattern.compile(pattern, flags), o como modificadores inline del estilo (?i) escritos dentro del patrón. Este capítulo cubre los flags que se usan a diario y cómo combinarlos.
Las dos formas de definir un flag
Cada flag tiene una constante en la clase Pattern. Se pasa como segundo argumento a compile:
Pattern p = Pattern.compile("error", Pattern.CASE_INSENSITIVE);El mismo comportamiento está disponible dentro del patrón como un modificador inline, por lo que una cadena de regex simple puede llevar sus propios flags sin necesidad de un segundo argumento:
Pattern p = Pattern.compile("(?i)error"); // whole pattern, case-insensitive
Pattern q = Pattern.compile("(?i:error) CODE"); // only the group is case-insensitiveLos flags inline son útiles cuando el patrón viaja como una cadena simple — un archivo de configuración, una columna de base de datos, una anotación — donde no se puede pasar también un int. La forma con constante es más clara cuando el flag forma parte del código.
Los flags que realmente usarás
| Constante | Inline | Efecto |
|---|---|---|
CASE_INSENSITIVE | (?i) | Coincide con letras ASCII independientemente del caso |
MULTILINE | (?m) | ^ y $ coinciden en cada límite de línea, no solo al inicio y fin de la cadena |
DOTALL | (?s) | . también coincide con terminadores de línea (s = "single line") |
COMMENTS | (?x) | Ignora los espacios en blanco sin escapar y trata # como comentario |
UNICODE_CASE | (?u) | Hace que CASE_INSENSITIVE doble letras Unicode, no solo ASCII |
UNICODE_CHARACTER_CLASS | (?U) | Hace que \w, \d, \b sigan las reglas Unicode |
LITERAL | — | Trata todo el patrón como texto simple, sin metacaracteres |
Una sorpresa común: CASE_INSENSITIVE por sí solo solo dobla ASCII. Para coincidir con letras acentuadas o no latinas sin distinción de caso, combínalo con UNICODE_CASE.
Insensibilidad a mayúsculas y minúsculas
Por defecto, una regex distingue mayúsculas de minúsculas, por lo que error no coincide con ERROR. Añade CASE_INSENSITIVE y ambas coinciden:
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(); // trueManejo de líneas: MULTILINE y DOTALL
Estos dos son independientes y a menudo se confunden. MULTILINE cambia los anclajes ^ y $; DOTALL cambia el 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(); // trueUsa MULTILINE cuando analices texto de registros o documentos de varias líneas línea por línea, y DOTALL cuando una sola coincidencia deba abarcar varias líneas (un bloque HTML, un registro de varias líneas).
Combinación de flags
Las constantes de flag son máscaras de bits, por lo que se combinan con el operador OR bit a bit |:
int flags = Pattern.MULTILINE | Pattern.CASE_INSENSITIVE | Pattern.DOTALL;
Pattern p = Pattern.compile("^error.*done$", flags);El equivalente inline apila las letras: (?ims) establece los tres. También puedes desactivar un flag dentro de un grupo con un signo menos: (?-i) desactiva la insensibilidad a mayúsculas para el resto del patrón.
Patrones legibles con COMMENTS
El flag COMMENTS (inline (?x)) permite que un patrón complejo sea más legible: los espacios en blanco sin escapar se ignoran y # comienza un comentario hasta el final de la línea. Esto convierte una línea ilegible en algo que puedes mantener:
Pattern phone = Pattern.compile("""
\\d{3} # area code
- # separator
\\d{4} # line number
""", Pattern.COMMENTS);
phone.matcher("555-1234").matches(); // trueDado que los espacios en blanco reales se ignoran, coincide con un espacio literal usando \\s, \\ o una clase de caracteres como [ ].
Un ejemplo práctico: una expresión, muchos flags
Este programa ejecuta el mismo conjunto de patrones con y sin flags para que puedas ver cómo cada flag invierte el resultado. Cuenta coincidencias sin distinción de mayúsculas, ancla líneas con MULTILINE, abarca saltos de línea con DOTALL, combina flags con | y usa tanto modificadores inline globales como con alcance limitado.
Lo que se puede extraer de la ejecución:
CASE_INSENSITIVEencontró 2 ocurrencias deerror(elERRORen mayúsculas y elerroren minúsculas), mientras que el patrón por defecto solo encontró 1 — prueba de que la distinción de mayúsculas está activa a menos que se solicite el flag.MULTILINEhizo que^error:.*$coincidiera con la línea central del registro e imprimieraerror: timeout; sin el flag,^y$solo anclarían los extremos de toda la cadena, por lo que esa línea interior nunca coincidiría.DOTALLpermitió quewarn.*infosaltara a través de los dos saltos de línea embebidos y coincidiera (true), mientras que el mismo patrón sin el flag devolviófalseporque.se detiene en un terminador de línea por defecto.- El patrón combinado
MULTILINE | CASE_INSENSITIVEcoincidió con^ERRORcontra una línea que comienza conerror:en minúsculas —trueconfirma que ambos flags se aplicaron a la vez desde una sola máscara OR bit a bit. - El
(?i:hello) WORLDcon alcance limitado coincidió conHELLO WORLD(true) pero no conHELLO world(false): el grupo(?i:...)dobló el caso solo parahello, dejando elWORLDfinal estrictamente sensible a mayúsculas — exactamente la precisión que ofrece el alcance inline.
Temas relacionados
- Expresiones regulares en Java — Introducción — cómo
PatternyMatcherencajan. - Pattern y Matcher — las clases que utilizan los flags anteriores.
- Sintaxis de Regex y Clases de caracteres — los metacaracteres que los flags modifican.
- Cuantificadores y Grupos — donde los flags inline con alcance como
(?i:...)son más útiles.