¿Qué son las expresiones regulares?
Las expresiones regulares (o regex) son una herramienta para describir patrones en las cadenas de texto.
Sirven para verificar si un texto cumple con una estructura determinada o para buscar y extraer partes del texto. Por ejemplo: Verificar si un correo electrónico tiene el formato adecuado; Comprobar si un DNI es correcto.
Símbolos básicos en Expresiones Regulares
Símbolo | Significado | Ejemplo de patrón | Qué detecta |
---|---|---|---|
[] | Un conjunto de caracteres posibles | [abc] | Una “a”, “b” o “c” |
- | Indica un rango | [a-z] | Cualquier letra minúscula |
? | El símbolo anterior puede aparecer cero o una vez | a?b | “b” o “ab” (ambas son válidas) |
* | El símbolo anterior puede aparecer cero o más veces | a*b | “b”, “ab”, “aaab” (cero o más “a” antes de “b”) |
+ | El símbolo anterior debe aparecer al menos una vez | a+b | “ab”, “aaab” (una o más “a” antes de “b”) |
{n,m} | El símbolo debe aparecer entre n y m veces | a{2,4} | “aa”, “aaa”, o “aaaa” (de 2 a 4 “a”) |
^ | Indica el inicio de la cadena | ^Hola | Solo valida si la cadena empieza con “Hola” |
$ | Indica el final de la cadena | mundo$ | Solo valida si la cadena termina con “mundo” |
. | Representa cualquier carácter | a.b | “aab”, “acb”, “a9b” (cualquier carácter entre “a” y “b”) |
\\d | Cualquier dígito (0-9) | \\d\\d | Dos dígitos, como “23” o “89” |
\\D | Cualquier carácter que no sea un dígito | \\D | “a”, “%”, ” ” (cualquier cosa menos números) |
\\s | Cualquier espacio en blanco | a\\sb | “a b” (una “a”, un espacio y una “b”) |
\\S | Cualquier no-espacio | \\S\\S | Dos caracteres sin espacios, como “ab”, “A9”, “%!” |
\\w | Cualquier letra, número o guión bajo (_ ) | \\w+ | Una palabra como “java”, “abc123”, “_variable” |
¿Qué son Pattern
y Matcher
?
Cuando quieres trabajar con expresiones regulares en Java, necesitas dos clases principales que vienen del paquete java.util.regex
:
Clase | ¿Qué hace? |
---|---|
Pattern | Compila la expresión regular para que esté lista para usar. |
Matcher | Aplica ese patrón a una cadena para ver si hay coincidencias. |
Ejemplo:
import java.util.regex.*;
public class EjemploRegex {
public static void main(String[] args) {
Pattern p = Pattern.compile("[01]+"); // patrón: uno o más ceros o unos
Matcher m = p.matcher("00001010"); // cadena a comprobar
if (m.matches())
System.out.println("Sí, contiene el patrón");
else
System.out.println("No, no contiene el patrón");
}
}
¿Cómo usar las clases Pattern
y Matcher
?
Paso 1: Crear un Pattern
a partir de la expresión regular (es decir, preparar el “molde”).
Pattern p = Pattern.compile("a+b"); // Buscamos una o más "a" seguidas de una "b"
Paso 2: Crear un Matcher
usando el Pattern
y la cadena de texto.
Matcher m = p.matcher("aaab");
Paso 3: Usar métodos del Matcher
para comprobar si encaja o buscar coincidencias.
System.out.println(m.matches()); // true
Métodos importantes de Matcher
Método | Explicación simple | Ejemplo |
---|---|---|
matches() | Verifica si toda la cadena cumple exactamente el patrón, de principio a fin. | Si buscas [0-9]+ y la cadena es "1234" , sí. Si es "abc1234" , no. |
find() | Busca una parte de la cadena que coincida con el patrón, no importa si toda la cadena cumple o no. | En "abc1234xyz" , find() con patrón [0-9]+ encuentra "1234" . |
lookingAt() | Solo mira el principio de la cadena: si el inicio encaja, da true , aunque el resto no coincida. | "123abc" con patrón [0-9]+ dará true , porque empieza con números. |
group() | Cuando encuentras algo con find() o matches() , group() te da el texto que coincide exactamente. | Si find() encontró "1234" , group() devuelve "1234" . |
Ejemplo:
import java.util.regex.*;
public class EjemploRegex {
public static void main(String[] args) {
Pattern p = Pattern.compile("[0-9]+");
Matcher m = p.matcher("abc1234xyz");
System.out.println(m.matches()); // false, NO toda la cadena son números
System.out.println(m.find()); // true, encontró "1234"
System.out.println(m.group()); // imprime "1234"
Matcher m2 = p.matcher("1234abc");
System.out.println(m2.lookingAt()); // true, empieza con números
}
}
Grupos en Expresiones Regulares
Los paréntesis ( )
sirven para crear grupos en la expresión:
- Permiten capturar partes específicas de una coincidencia.
- Cada grupo tiene un número (grupo 1, grupo 2, etc).
Ejemplo:
import java.util.regex.*;
public class GruposRegex {
public static void main(String[] args) {
Pattern p = Pattern.compile("([XY]?)([0-9]{1,9})([A-Za-z])");
Matcher m = p.matcher("X123456789Z Y00110011M 999999T");
while (m.find()) {
System.out.println("Letra inicial (opcional): " + m.group(1));
System.out.println("Número: " + m.group(2));
System.out.println("Letra final: " + m.group(3));
}
}
}
¿Qué hace este código?
- Encuentra cada DNI o NIE en el texto.
- Extrae:
- La letra inicial (grupo 1).
- El número (grupo 2).
- La letra final (grupo 3).
Secuencias de Escape
Caracteres como (
, [
, ]
, .
normalmente tienen un significado especial. Si quieres buscarlos como texto normal, debes escaparlos usando \\
.
Carácter | Secuencia de Escape | Ejemplo de Uso | ¿Qué hace? |
---|---|---|---|
( | \\( | Pattern p = Pattern.compile("\\(hola\\)"); | Coincide literalmente con “(hola)” |
) | \\) | Pattern p = Pattern.compile("mundo\\)"); | Coincide con el texto “mundo)” |
[ | \\[ | Pattern p = Pattern.compile("\\[abc\\]"); | Coincide literalmente con “[abc]” |
] | \\] | Pattern p = Pattern.compile("abc\\]"); | Coincide con “abc]” |
. | \\. | Pattern p = Pattern.compile("a\\.b"); | Coincide con “a.b” (sin escaparlo, el punto sería “cualquier carácter”) |
Ejemplo:
import java.util.regex.*;
public class EjemploEscape {
public static void main(String[] args) {
// Crear un patrón con secuencias de escape para caracteres especiales
String texto = "Este es un ejemplo con caracteres especiales: (abc), [def], a.b y (xyz).";
// Definir las expresiones regulares con las secuencias de escape
Pattern p1 = Pattern.compile("\\(abc\\)"); // Busca "(abc)"
Pattern p2 = Pattern.compile("\\[def\\]"); // Busca "[def]"
Pattern p3 = Pattern.compile("a\\.b"); // Busca "a.b"
Pattern p4 = Pattern.compile("\\(xyz\\)"); // Busca "(xyz)"
// Crear Matcher para cada patrón
Matcher m1 = p1.matcher(texto);
Matcher m2 = p2.matcher(texto);
Matcher m3 = p3.matcher(texto);
Matcher m4 = p4.matcher(texto);
// Verificar si los patrones se encuentran en el texto
if (m1.find()) {
System.out.println("Encontrado: " + m1.group()); // Salida esperada: (abc)
} else {
System.out.println("No se encontró: (abc)");
}
if (m2.find()) {
System.out.println("Encontrado: " + m2.group()); // Salida esperada: [def]
} else {
System.out.println("No se encontró: [def]");
}
if (m3.find()) {
System.out.println("Encontrado: " + m3.group()); // Salida esperada: a.b
} else {
System.out.println("No se encontró: a.b");
}
if (m4.find()) {
System.out.println("Encontrado: " + m4.group()); // Salida esperada: (xyz)
} else {
System.out.println("No se encontró: (xyz)");
}
}
}
Actividades de programación
Actividad 1: Validar una dirección de correo electrónico
Escribe un programa que utilice expresiones regulares para validar la siguiente dirección de correo electrónico: usuario@dominio.com
import java.util.regex.*;
public class ValidarCorreo {
public static void main(String[] args) {
String correo = “usuario@dominio.com”;
Pattern p = Pattern.compile(“^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$”);
Matcher m = p.matcher(correo);
if (m.matches()) {
System.out.println(“Correo válido”);
} else {
System.out.println(“Correo no válido”);
}
}
}
Actividad 2: Extracción de números de una cadena
Dado un texto que puede contener números, escribe un programa que extraiga todos los números de la cadena y los imprima por separado. Por ejemplo, si la cadena es “Tengo 2 gatos y 3 perros”, el programa debe imprimir “2” y “3”.
import java.util.regex.*;
public class ExtraerNumeros {
public static void main(String[] args) {
String texto = “Tengo 2 gatos y 3 perros”;
Pattern p = Pattern.compile(“\\d+”);
Matcher m = p.matcher(texto);
while (m.find()) {
System.out.println(m.group());
}
}
}
Actividad 3: Comprobación de un formato de fecha (DD/MM/YYYY)
Escribe un programa que valide si una fecha (por ejemplo 31/12/2023) tiene el formato correcto DD/MM/YYYY . La expresión regular debe:
- Validar que los días estén entre 01 y 31.
- Validar que los meses estén entre 01 y 12.
- Validar que el año sea un número de 4 dígitos.
import java.util.regex.*;
public class ValidarFecha {
public static void main(String[] args) {
String fecha = “31/12/2023”;
Pattern p = Pattern.compile(“^(0[1-9]|[12][0-9]|3[01])/(0[1-9]|1[0-2])/\\d{4}$”);
Matcher m = p.matcher(fecha);
if (m.matches()) {
System.out.println(“Fecha válida”);
} else {
System.out.println(“Fecha no válida”);
}
}
}
Actividad 4: Contar palabras en una cadena
Escribe un programa que cuente cuántas palabras hay en una cadena. (Ejemplo de cadena: El perro corre rápido).
import java.util.regex.*;
public class ContarPalabras {
public static void main(String[] args) {
String texto = “El perro corre rápido”;
Pattern p = Pattern.compile(“\\w+”);
Matcher m = p.matcher(texto);
int count = 0;
while (m.find()) {
count++;
}
System.out.println(“Número de palabras: ” + count);
}
}
Actividad 5: Búsqueda y reemplazo de texto
Escribe un programa que busque todas las ocurrencias de una palabra en una cadena y la reemplace por otra. Por ejemplo, si el texto es “La bombilla brilla muy fuerte” y la palabra a reemplazar es “bombilla”, el programa debe reemplazarla por “luna” resultando en “La luna brilla muy fuerte”.
import java.util.regex.*;
public class ReemplazarPalabra {
public static void main(String[] args) {
String texto = “La bombilla brilla muy fuerte”;
Pattern p = Pattern.compile(“\\bbombilla\\b”);
Matcher m = p.matcher(texto);
String resultado = m.replaceAll(“luna”);
System.out.println(“Texto después del reemplazo: ” + resultado);
}
}