W3docs

Introducción a las Expresiones Regulares en Java

Introducción a las expresiones regulares en Java con el paquete java.util.regex.

Una expresión regular (regex) es un patrón compacto que describe un conjunto de cadenas. En Java, el paquete java.util.regex convierte estos patrones en un motor de coincidencia pequeño y rápido que puedes aplicar a cualquier texto — para validar entradas, buscar subcadenas, extraer campos o reescribir contenido. Este capítulo presenta las partes fundamentales antes de que empieces a escribir tus propios patrones.

Qué es una Expresión Regular

Una regex es simplemente una cadena escrita en una sintaxis especial, pero Java no la interpreta carácter por carácter cada vez. En cambio, compilas el patrón una vez en un objeto Pattern y luego lo aplicas a la entrada mediante un Matcher. La forma compilada es una máquina de estados eficiente, por lo que reutilizar un Pattern en muchas entradas es mucho más económico que recompilarlo.

Los patrones describen estructura: un literal como cat coincide exactamente con esas letras, mientras que los metacaracteres describen formas — \d es cualquier dígito, + significa "uno o más", . significa "cualquier carácter". Combínalos y podrás describir números de teléfono, correos electrónicos o líneas de registro en una sola línea de código.

import java.util.regex.Pattern;

public class FirstPattern {
    public static void main(String[] args) {
        // Compile the pattern once; reuse the result.
        Pattern digits = Pattern.compile("\\d+");
        System.out.println(digits.matcher("abc123").find()); // true
        System.out.println(digits.matcher("hello").find());  // false
    }
}

Observa la doble barra invertida: \d en regex debe escribirse \\d en un literal de cadena de Java, porque el compilador de Java consume una barra invertida primero.

Pattern y Matcher

Dos clases hacen casi todo el trabajo. Pattern es el plano compilado, reutilizable y seguro para subprocesos. Matcher es el motor con estado que ejecuta ese plano contra una entrada específica — lleva el registro de dónde estás en el texto, qué grupos se capturaron y dónde aterrizó la última coincidencia. Crea un nuevo Matcher por cada entrada; nunca compartas uno entre subprocesos.

TipoFunción
PatternEl patrón compilado. Inmutable, seguro para subprocesos y reutilizable.
MatcherAplica un Pattern a una entrada. Mantiene el estado de coincidencia.
Pattern.compile(regex)Construye un Pattern a partir de una cadena regex.
pattern.matcher(input)Devuelve un Matcher vinculado a esa entrada.
String.matches(regex)Método de conveniencia que compila y verifica la coincidencia completa en una sola llamada.
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class PatternAndMatcher {
    public static void main(String[] args) {
        Pattern p = Pattern.compile("\\w+@\\w+\\.\\w+");
        Matcher m = p.matcher("ping me at [email protected] please");
        if (m.find()) {
            System.out.println("Found email: " + m.group());
        }
    }
}

find() vs matches()

El error más común entre principiantes es confundir las dos formas de ejecutar un patrón. matches() requiere que la entrada completa coincida con el patrón de principio a fin. find() busca cualquier subcadena que coincida y puede llamarse repetidamente para recorrer cada ocurrencia. lookingAt() se sitúa entre ambos: se ancla al inicio pero no requiere que la coincidencia llegue al final.

Método¿Anclado al inicio?¿Debe coincidir hasta el final?¿Repetible?
matches()no
lookingAt()nono
find()nono
import java.util.regex.Pattern;

public class FindVsMatches {
    public static void main(String[] args) {
        Pattern p = Pattern.compile("\\d+");
        System.out.println(p.matcher("42").matches());        // true  (whole input)
        System.out.println(p.matcher("age 42").matches());    // false (extra text)
        System.out.println(p.matcher("age 42").find());       // true  (substring)
        System.out.println(p.matcher("age 42").lookingAt());  // false (no digit at start)
    }
}

Sintaxis Común con la que Construirás

La mayoría de los patrones reales se ensamblan a partir de un pequeño vocabulario de bloques de construcción: clases de caracteres, atajos predefinidos, cuantificadores y anclas. Aprenderlos te llevará gran parte del camino. Cada construcción tiene su propio capítulo dedicado — consulta Sintaxis de Regex, clases de caracteres y cuantificadores para los detalles completos.

ConstrucciónSignificadoEjemplo
.Cualquier carácter individual (excepto nueva línea)a.c coincide con abc, axc
\d \w \sDígito, carácter de palabra, espacio en blanco\d\d coincide con 42
[abc]Cualquiera de a, b, c[aeiou] coincide con una vocal
[^abc]Cualquier carácter excepto a, b, c[^0-9] coincide con un no dígito
* + ?Cero o más, uno o más, cero o unoab+ coincide con ab, abb
{n} {n,m}Exactamente n, entre n y m\d{3} coincide con 555
^ $Inicio, fin de la entrada/línea^Hi coincide con un Hi inicial
(...)Grupo de captura(\d{4}) captura cuatro dígitos
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class GroupsExample {
    public static void main(String[] args) {
        // Two capturing groups: year and month.
        Pattern date = Pattern.compile("(\\d{4})-(\\d{2})");
        Matcher m = date.matcher("Released 2025-11 to users");
        if (m.find()) {
            System.out.println("Full: " + m.group(0)); // 2025-11
            System.out.println("Year: " + m.group(1)); // 2025
            System.out.println("Month: " + m.group(2)); // 11
        }
    }
}

Ejemplo Práctico

El programa a continuación compila un patrón de número de teléfono y ejercita toda la API sobre él: recorre cada coincidencia con find(), lee los grupos de captura y las posiciones de coincidencia, contrasta find() con matches() y reescribe el texto con replaceAll(). Ejecútalo para ver el motor en acción.

java— editable, runs on the server

Qué extraer de la ejecución:

  • find() se llama en un bucle y devuelve dos coincidencias, por lo que el mismo Matcher recorre el texto una ocurrencia a la vez hasta devolver false.
  • group(1) y group(2) devuelven las subpartes entre paréntesis (555 y 1234), mientras que group() sin argumento devuelve la coincidencia completa.
  • start() y end() informan los desplazamientos de caracteres de cada coincidencia, que es cómo resaltarías o dividirías el texto original.
  • matches() sobre la oración completa imprime false porque el patrón no cubre toda la cadena, mientras que "555-1234" solo imprime true — prueba de que matches() es solo para la entrada completa.
  • replaceAll("XXX-XXXX") reescribe cada coincidencia en un solo paso, produciendo la oración enmascarada y mostrando cómo los patrones impulsan la transformación de texto.

Dónde Ir a Continuación

Ahora que conoces las partes en movimiento — Pattern, Matcher y la diferencia entre find() y matches() — profundiza con los capítulos centrados en cada tema:

Práctica

Práctica
¿Cuál es la diferencia clave entre Matcher.matches() y Matcher.find()?
¿Cuál es la diferencia clave entre Matcher.matches() y Matcher.find()?
Was this page helpful?