Una librería con libros holográficos hechos de código fuente.

Expresiones Regulares en Java: conceptos avanzados

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:

FlagDescripción
Pattern.CASE_INSENSITIVEIgnora mayúsculas y minúsculas.
Pattern.MULTILINEHace que ^ y $ funcionen por línea en lugar de todo el texto.
Pattern.DOTALLPermite que . coincida con saltos de línea.
Pattern.UNICODE_CHARACTER_CLASSPermite 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:

TipoDescripciónEjemplo
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

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.