REGEXP_LIKE

La función REGEXP_LIKE() es la versión funcional del operador REGEXP. Aunque ambos hacen lo mismo en su forma básica, REGEXP_LIKE() ofrece un tercer parámetro que permite controlar el comportamiento de la coincidencia: sensibilidad a mayúsculas, modo multilínea y tratamiento del punto con saltos de línea. Este control adicional la convierte en la opción preferida cuando necesitas ajustar cómo se interpreta el patrón.

REGEXP_LIKE() fue introducida en MySQL 8.0 como parte de la familia de funciones regulares basadas en el motor ICU, junto con REGEXP_INSTR(), REGEXP_REPLACE() y REGEXP_SUBSTR().

Sintaxis

REGEXP_LIKE(expresion, patron [, modo])

El primer argumento es la cadena que se evalúa, el segundo es el patrón de expresión regular y el tercero, opcional, es una cadena con uno o más caracteres que modifican el comportamiento de la coincidencia:

ModoSignificado
'c'Coincidencia sensible a mayúsculas y minúsculas (case-sensitive)
'i'Coincidencia insensible a mayúsculas y minúsculas (case-insensitive)
'm'Modo multilínea: ^ y $ coinciden con inicio y fin de cada línea, no solo de la cadena
'n'El punto (.) también coincide con caracteres de salto de línea
'u'Terminaciones de línea solo Unix (\n), no Windows (\r\n)

La función devuelve 1 si hay coincidencia, 0 si no la hay y NULL si algún argumento es NULL. Puedes combinar varios caracteres de modo en una sola cadena, como 'ic' o 'mn'. Si se especifican modos contradictorios como 'ci', el último carácter prevalece.

Comportamiento básico

En su forma más simple, REGEXP_LIKE() se comporta exactamente como el operador REGEXP:

-- Estas dos consultas producen el mismo resultado
SELECT nombre FROM productos WHERE nombre REGEXP 'Samsung';
SELECT nombre FROM productos WHERE REGEXP_LIKE(nombre, 'Samsung');
nombre
Samsung Galaxy S24
Samsung Galaxy Tab S9
Samsung Monitor 32"

La diferencia fundamental aparece cuando necesitas controlar la sensibilidad a mayúsculas. Con el operador REGEXP, debes recurrir a la palabra clave BINARY, mientras que con REGEXP_LIKE() simplemente usas el parámetro de modo:

-- Con operador REGEXP (sintaxis menos elegante)
SELECT nombre FROM productos WHERE nombre REGEXP BINARY 'samsung';
 
-- Con REGEXP_LIKE (sintaxis más clara)
SELECT nombre FROM productos WHERE REGEXP_LIKE(nombre, 'samsung', 'c');

Ambas consultas devuelven un resultado vacío porque ningún producto tiene "samsung" en minúsculas. El modo 'c' indica coincidencia case-sensitive de forma clara y explícita.

Modo case-sensitive e case-insensitive

El modo 'c' (case-sensitive) es especialmente útil cuando trabajas con datos donde las mayúsculas son significativas, como contraseñas parciales, códigos de producto o identificadores técnicos:

SELECT nombre, codigo
FROM productos
WHERE REGEXP_LIKE(codigo, '^[a-z]', 'c');
nombrecodigo
Producto temporaltmp-001
Muestra gratuitamue-099

Esta consulta encuentra productos cuyo código empieza con una letra minúscula, lo cual podría indicar productos provisionales que no siguen el estándar de códigos en mayúsculas.

El modo 'i' fuerza la comparación insensible a mayúsculas independientemente de la collation de la columna. Esto es útil cuando trabajas con columnas que tienen collation binaria o case-sensitive pero quieres ignorar la diferencia:

-- Buscar sin importar mayúsculas, incluso en columnas con collation binaria
SELECT nombre, email
FROM usuarios
WHERE REGEXP_LIKE(email, '@GMAIL\\.COM$', 'i');
nombreemail
María Garcíamaria@gmail.com
Carlos LópezCARLOS@Gmail.Com
Ana Martínezana@GMAIL.COM

Las tres variantes de escritura del dominio coinciden gracias al modo 'i'.

Modo multilínea

El modo 'm' cambia el comportamiento de las anclas ^ y $. Sin este modo, ^ solo coincide con el inicio de la cadena completa y $ con su final. Con el modo multilínea, estas anclas también coinciden con el inicio y fin de cada línea dentro de la cadena.

Esto es relevante cuando almacenas texto con saltos de línea en una sola columna, como direcciones, descripciones multilínea o notas:

SELECT
    id,
    notas,
    REGEXP_LIKE(notas, '^URGENTE', 'm') AS tiene_urgente
FROM pedidos;
idnotastiene_urgente
101Entregar antes del viernes\nURGENTE: cliente VIP1
102Pedido estándar0
103URGENTE: reposición de stock1

Sin el modo 'm', el pedido 101 no coincidiría porque "URGENTE" no está al inicio de la cadena completa, sino al inicio de la segunda línea. Con 'm', el ancla ^ coincide con el inicio de cada línea y la búsqueda es exitosa.

Otro ejemplo práctico sería buscar líneas específicas dentro de un campo de texto estructurado:

-- Buscar descripciones que tengan alguna línea que empiece por "Incluye:"
SELECT nombre, descripcion
FROM productos
WHERE REGEXP_LIKE(descripcion, '^Incluye:', 'm');
nombredescripcion
Pack gaming completoTeclado mecánico RGB\nIncluye: ratón y alfombrilla
Kit de herramientas50 piezas profesionales\nIncluye: maletín de transporte

Modo dot-matches-newline

Por defecto, el metacarácter punto (.) coincide con cualquier carácter excepto el salto de línea. El modo 'n' cambia este comportamiento para que el punto también coincida con \n:

-- Sin modo 'n': el punto no cruza líneas
SELECT REGEXP_LIKE('primera\nsegunda', 'primera.segunda') AS sin_n;
 
-- Con modo 'n': el punto coincide con el salto de línea
SELECT REGEXP_LIKE('primera\nsegunda', 'primera.segunda', 'n') AS con_n;
sin_n
0
con_n
1

Este modo es útil cuando necesitas que un patrón abarque múltiples líneas dentro de un campo de texto.

Combinación de modos

Puedes combinar varios caracteres de modo en una sola cadena. El orden no importa, salvo cuando hay modos contradictorios:

-- Multilínea + insensible a mayúsculas
SELECT nombre, notas
FROM pedidos
WHERE REGEXP_LIKE(notas, '^urgente', 'mi');
nombrenotas
Pedido 101Entregar antes del viernes\nURGENTE: cliente VIP
Pedido 103urgente: reposición de stock
Pedido 107Nota interna\nUrgente: confirmar dirección

La combinación 'mi' activa tanto el modo multilínea como la insensibilidad a mayúsculas. El patrón ^urgente coincide con "URGENTE", "urgente" y "Urgente", tanto al inicio de la cadena como al inicio de cualquier línea.

Si combinas 'c' e 'i' en la misma cadena de modo, prevalece el último:

-- 'ci' -> prevalece 'i' (insensible)
SELECT REGEXP_LIKE('ABC', 'abc', 'ci') AS resultado;
resultado
1

Caso práctico: auditoría de datos de usuarios

En un sistema donde los usuarios ingresan datos manualmente, REGEXP_LIKE() es ideal para auditar la calidad de la información. Veamos cómo detectar problemas comunes:

SELECT
    id,
    nombre,
    CASE
        WHEN NOT REGEXP_LIKE(nombre, '^[A-ZÁÉÍÓÚÑ]', 'c')
            THEN 'No empieza por mayúscula'
        WHEN REGEXP_LIKE(nombre, '[0-9]')
            THEN 'Contiene números'
        WHEN REGEXP_LIKE(nombre, '  ')
            THEN 'Espacios dobles'
        WHEN REGEXP_LIKE(nombre, '(^\\s|\\s$)')
            THEN 'Espacios al inicio o final'
        ELSE 'OK'
    END AS problema
FROM clientes
WHERE NOT REGEXP_LIKE(nombre, '^[A-ZÁÉÍÓÚÑ][a-záéíóúñ]+ [A-ZÁÉÍÓÚÑ][a-záéíóúñ]+', 'c')
ORDER BY problema;
idnombreproblema
15carlos lópezNo empieza por mayúscula
23María García2Contiene números
31Ana MartínezEspacios dobles
42Pedro RuizEspacios al inicio o final

El modo 'c' es esencial aquí porque necesitamos distinguir entre mayúsculas y minúsculas para detectar nombres que no empiezan con mayúscula.

Caso práctico: filtrar registros con patrones complejos

Supón que tienes una tabla de pedidos con un campo de notas de texto libre y necesitas encontrar pedidos que mencionan devoluciones o cancelaciones:

SELECT
    id,
    fecha,
    total,
    notas
FROM pedidos
WHERE REGEXP_LIKE(
    notas,
    '(devol(ución|ver)|cancel(ación|ar|ado)|reembols(o|ar))',
    'i'
);
idfechatotalnotas
10452025-03-1589.99Cliente solicita devolución por defecto
10782025-03-18245.00Cancelado por falta de stock
11022025-03-2059.50Pendiente de reembolso bancario
11302025-03-22175.00Devolver al almacén central

El patrón usa alternancia y grupos para capturar todas las variantes de las palabras relacionadas: "devolución", "devolver", "cancelación", "cancelar", "cancelado", "reembolso" y "reembolsar". El modo 'i' asegura que funcione independientemente de si el texto está en mayúsculas o minúsculas.

Manejo de NULL

REGEXP_LIKE() devuelve NULL si cualquiera de sus argumentos es NULL:

SELECT
    nombre,
    telefono,
    REGEXP_LIKE(telefono, '^[0-9]+$') AS es_numerico,
    COALESCE(REGEXP_LIKE(telefono, '^[0-9]+$'), 0) AS es_numerico_seguro
FROM clientes;
nombretelefonoes_numericoes_numerico_seguro
María García61234567811
Carlos López+34-678-901-23400
Pedro RuizNULLNULL0

La función COALESCE convierte el NULL en 0, lo cual es útil cuando necesitas un resultado booleano garantizado para usarlo en cálculos o agregaciones.

Combinación con otras funciones

REGEXP_LIKE() se integra bien con funciones de agregación para generar informes de calidad de datos:

SELECT
    COUNT(*) AS total_clientes,
    SUM(REGEXP_LIKE(email, '^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$')) AS emails_validos,
    SUM(1 - COALESCE(REGEXP_LIKE(email, '^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$'), 0)) AS emails_invalidos,
    ROUND(
        100.0 * SUM(REGEXP_LIKE(email, '^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$'))
        / COUNT(*),
        1
    ) AS porcentaje_validos
FROM clientes;
total_clientesemails_validosemails_invalidosporcentaje_validos
2502371394.8

Este tipo de consulta es invaluable para medir la calidad de los datos antes de una migración o para un informe periódico de integridad.

También puedes usarla en restricciones CHECK (MySQL 8.0.16+) para validar datos al insertarlos:

CREATE TABLE usuarios_v2 (
    id INT AUTO_INCREMENT PRIMARY KEY,
    email VARCHAR(255) NOT NULL,
    telefono VARCHAR(20),
    codigo_postal VARCHAR(10),
    CONSTRAINT chk_email CHECK (
        REGEXP_LIKE(email, '^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$')
    ),
    CONSTRAINT chk_telefono CHECK (
        telefono IS NULL OR REGEXP_LIKE(telefono, '^(\\+34)?[6-9][0-9]{8}$')
    ),
    CONSTRAINT chk_cp CHECK (
        codigo_postal IS NULL OR REGEXP_LIKE(codigo_postal, '^[0-5][0-9]{4}$')
    )
);

Con estas restricciones, MySQL rechazará automáticamente cualquier inserción o actualización que no cumpla los patrones definidos, asegurando la integridad de los datos desde la propia base de datos.

En el siguiente artículo veremos REGEXP_INSTR para encontrar la posición de una coincidencia.

Escrito por Eduardo Lázaro