1. Introducción
En esta tercera y última entrada sobre expresiones regulares en Java, consolidaremos lo aprendido y abordaremos aspectos avanzados que te permitirán su uso en escenarios reales. Nos enfocaremos en:
- Uso de flags para modificar el comportamiento de las expresiones regulares.
- Expresiones regulares no codiciosas y optimización de patrones.
- Uso de lookaheads y lookbehinds.
- Casos de uso aplicados en procesamiento de texto.
- Buenas prácticas y errores comunes.
2. Flags en Expresiones Regulares
Los flags permiten modificar el comportamiento de las expresiones regulares en Java. Se utilizan con el método Pattern.compile()
.
Flags más comunes:
Flag | Descripción |
---|---|
Pattern.CASE_INSENSITIVE | Ignora mayúsculas y minúsculas. |
Pattern.MULTILINE | Hace que ^ y $ funcionen por línea en lugar de todo el texto. |
Pattern.DOTALL | Permite que . coincida con saltos de línea. |
Pattern.UNICODE_CHARACTER_CLASS | Permite que \w , \d , etc., reconozcan caracteres Unicode. |
Ejemplo de uso de flags:
import java.util.regex.*;
public class FlagsEjemplo {
public static void main(String[] args) {
String texto = "Hola mundo\nHola JAVA";
Pattern patron = Pattern.compile("^Hola", Pattern.MULTILINE);
Matcher matcher = patron.matcher(texto);
while (matcher.find()) {
System.out.println("Coincidencia en posición: " + matcher.start());
}
}
}
Salida:
Coincidencia en posición: 0
Coincidencia en posición: 11
3. Expresiones No Codiciosas
Por defecto, los cuantificadores *
, +
y {n,m}
son codiciosos, lo que significa que intentan capturar la mayor cantidad de texto posible. Se pueden hacer no codiciosos añadiendo ?
.
Ejemplo de comparación:
String texto = "<p>Hola</p> <p>Mundo</p>";
Pattern codicioso = Pattern.compile("<p>.*</p>");
Pattern noCodicioso = Pattern.compile("<p>.*?</p>");
Matcher matcher1 = codicioso.matcher(texto);
Matcher matcher2 = noCodicioso.matcher(texto);
Codicioso: Coincidirá con todo "<p>Hola</p> <p>Mundo</p>"
No codicioso: Coincidirá con "<p>Hola</p>"
y "<p>Mundo</p>"
4. Lookaheads y Lookbehinds
Los lookaheads y lookbehinds o aserciones de avance y retroceso permiten validar lo que precede o sigue a un patrón sin incluirlo en la coincidencia.
Tipos:
Tipo | Descripción | Ejemplo |
---|---|---|
Positive Lookahead (?=...) | Asegura que después del patrón venga algo. | \d(?=USD) (Captura dígitos seguidos de «USD»)hola(?=mundo) coincidirá con «hola» solo si está seguido por «mundo». |
Negative Lookahead (?!...) | Asegura que después del patrón NO venga algo. | \d(?!USD) (Captura dígitos que NO vayan seguidos de «USD») |
Positive Lookbehind (?<=...) | Asegura que antes del patrón venga algo. | (?<=EUR)\d+ (Captura números precedidos por «EUR»)(?<=http://)www.google.com coincidirá con «www.google.com» solo si está precedido por «http://». |
Negative Lookbehind (?<!...) | Asegura que antes del patrón NO venga algo. | (?<!EUR)\d+ (Captura números que NO estén precedidos por «EUR») |
Ejemplo práctico:
String texto = "Precio: 50USD, 40EUR, 30USD";
Pattern patron = Pattern.compile("\d+(?=USD)");
Matcher matcher = patron.matcher(texto);
while (matcher.find()) {
System.out.println("Precio en USD: " + matcher.group());
}
Salida:
Precio en USD: 50
Precio en USD: 30
5. Casos de Uso Aplicados
5.1 Validación de Números de Teléfono
String regex = "\\+\\d{2}\s\\d{9}"; // Formato +34 612345678
String telefono = "+34 612345678";
System.out.println(telefono.matches(regex)); // true
5.2 Extracción de Correos Electrónicos
String texto = "Contacta a juan@mail.com o info@empresa.com";
Pattern patron = Pattern.compile("[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}");
Matcher matcher = patron.matcher(texto);
while (matcher.find()) {
System.out.println("Correo encontrado: " + matcher.group());
}
6. Buenas Prácticas y Errores Comunes
- Evitar expresiones demasiado complejas: pueden afectar el rendimiento.
- Utilizar
Pattern.compile()
una sola vez si se va a usar la expresión varias veces. - Cuidado con el uso de
.*
: puede causar capturas inesperadas. - Validar expresiones en un simulador como Regex101.
7. Conclusión
Hemos profundizado en conceptos avanzados de expresiones regulares en Java. Ahora puedes utilizarlas de manera eficiente en validaciones, análisis y manipulación de texto. ¡Sigue practicando y verás lo útiles que son!
¿Listo para el próximo reto? 🚀
Deja una respuesta