Saltar al contenido
APFerrer
Volver al blog
Trucos rápidosTrucos rápidos

Regex para gente que odia regex: 8 patrones que salvan la semana

APFerrer06 de agosto de 202615 min
Entradilla

Guía práctica de expresiones regulares para validar datos españoles sin tocar código.

Regex para gente que odia regex: 8 patrones que salvan la semana

Guía práctica de expresiones regulares para validar datos españoles sin tocar código.

Las expresiones regulares (regex) tienen fama de terroríficas. Ves un patrón como ^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$ y quieres cerrar la pestaña. Pero la realidad es más sencilla: regex es solo un idioma para decir "quiero encontrar esto" o "quiero aceptar aquello". Y una vez dominas ocho patrones básicos, resuelves el 90% de las validaciones del día a día.

Este artículo te enseña exactamente eso: los ocho patrones que necesitas para España, cómo funcionan, dónde probarlos, cómo copiarlos sin miedo a Sheets, Docs o tu editor de código, y cómo integrarlos en tu flujo de datos. Sin jerga innecesaria.

Los tres conceptos que necesitas saber

Antes de los patrones, tres frases.

Clases de caracteres. Entre corchetes [a-z] significa "cualquier letra minúscula". [0-9] significa "cualquier dígito". [a-zA-Z0-9] significa "letra o número". Eso es todo.

Cuantificadores. Controlan cuántas veces se repite algo.

  • + = una o más veces
  • * = cero o más veces
  • {n} = exactamente n veces
  • {n,m} = entre n y m veces
  • ? = cero o una vez (opcional)

Anclas. Marcan dónde empieza o termina.

  • ^ = inicio de la cadena
  • $ = final de la cadena

Ejemplo: ^[A-Z] significa "comienza con una mayúscula". [0-9]$ significa "termina con un número". Eso es todo lo que necesitas para entender cada patrón que sigue.

Los 4 conceptos que te ahorrarán tiempo

Una vez asimilas los tres conceptos básicos, estos cuatro te liberan de escribir patrones enredados.

Grupos capturadores: (patrón)

Los paréntesis agrupan partes de tu patrón. Sirven para dos cosas: aplicar cuantificadores a múltiples caracteres y reutilizar lo capturado después.

Ejemplo: (\+34)? significa "el grupo completo +34 es opcional". Sin paréntesis, +34? significaría "3 seguido de cero o uno 4", que no es lo que quieres.

En Sheets, REGEXEXTRACT(texto, "(patrón)") devuelve solo lo que está dentro del paréntesis. Si escribes REGEXEXTRACT("aida@apferrer.com", "^([a-z]+)@"), obtienes "aida".

Lookahead: (?=patrón)

Mira hacia adelante sin consumir caracteres. Sirve para validar que algo viene después, sin incluirlo en la coincidencia.

Ejemplo: ^(?=.*[A-Z]) en una contraseña significa "comprueba que en algún punto hay una mayúscula", pero no extrae esa mayúscula. Se usa mucho en validación de passwords.

Backreferences: \1, \2

Reutiliza lo que capturaste. Si capturaste ([a-z]+) en tu patrón (primer grupo), luego escribes \1 para referirte exactamente a lo que ya coincidió.

Ejemplo: ^([a-z])\1+$ encuentra palabras como "aaa", "bbb" (la misma letra repetida). El \1 dice "lo que capturó el grupo 1, otra vez".

En Sheets no está disponible directamente, pero en Apps Script sí.

Flags: /patrón/flags

Modifican el comportamiento global del patrón. Los más usados:

  • i = insensible a mayúsculas/minúsculas
  • g = aplica a todas las coincidencias, no solo la primera
  • m = modo multilínea (^ y $ consideran saltos de línea)

En Google Sheets, algunos flags se soportan en REGEXMATCH(..., "patrón"), pero depende de la función.


Dónde probar antes de usarlo

Usa regex101.com. Es gratis, sin registro, y explica cada parte mientras escribes.

Proceso: Pega el patrón en la caja de arriba, elige PCRE2 en el selector de la izquierda, escribe un texto de prueba debajo, y verás al instante si coincide o no. Si algo no funciona, regex101 te lo marca en rojo. Así ganas confianza antes de meterlo en Sheets.

Alternativamente, si usas VS Code, instala RegEx Previewer y prueba directamente en tu editor.


Patrón 1: Email

Qué valida: Formato básico de correo (usuario@dominio.extensión).

Patrón regex:

^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$

Desglose: Comienza (^), una o más caracteres alfanuméricos o especiales ([a-zA-Z0-9._%+-]+), arroba (@), nombre del dominio ([a-zA-Z0-9.-]+), punto literal (\.), extensión de al menos 2 letras ([a-zA-Z]{2,}), termina ($).

Ejemplos válidos:

  • aida@apferrer.com
  • contacto.legal@empresa-ejemplo.es
  • usuario+etiqueta@dominio.co.uk

Ejemplos inválidos:

  • aida@apferrer (falta extensión)
  • @apferrer.com (falta usuario)
  • aida apferrer.com (falta arroba)

Casos de uso reales:

  1. TechStart Solutions recibe inscritos en webinars. Necesita validar que cada email tenga formato correcto antes de enviar confirmación. Con REGEXMATCH descarta ~15% de entradas duplicadas o mal tipadas.

  2. Consultoría Administrativo gestiona contactos de clientes en Sheets. Usa esta regex para marcar filas rojas si un email parece inválido, así el equipo de ventas puede llamar antes de enviar propuestas.

  3. E-learning Platform valida emails al registrar usuarios. Este patrón rechaza usuario@.com y usuario@dominio en el lado del cliente, evitando envíos fallidos.

Variantes según rigidez:

  • Más flexible (acepta más formatos): ^.+@.+\..+$ (muy permisivo, solo comprueba @, al menos un carácter antes y después, y un punto)
  • Actual (recomendado): El patrón de arriba
  • Más estricto (rechaza algunos válidos): ^[a-zA-Z0-9]+@[a-zA-Z0-9]+\.[a-zA-Z]{2,}$ (sin puntos ni guiones en usuario o dominio)

Falsos positivos y negativos:

  • Falso positivo: test+123@sub-domain.example.co.uk se acepta (correcto, es válido).
  • Falso negativo: usuario_nombre@dominio.ejemplo.info se rechaza si tu patrón no incluye el guion bajo (inclúyelo: [a-zA-Z0-9._%-]+).
  • Falso positivo raro: test@.com. se acepta si usas un patrón menos cuidadoso. El patrón recomendado lo rechaza.

En Google Sheets:

=REGEXMATCH(A1,"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$")

Devuelve VERDADERO si es email válido, FALSO si no. Para extraer solo el dominio:

=REGEXEXTRACT(A1,"@([a-zA-Z0-9.-]+)")

Devuelve apferrer.com desde aida@apferrer.com.

Para reemplazar todos los puntos por guiones (raramente útil, solo ejemplo):

=REGEXREPLACE(A1,"\.","-")

Convierte aida.perez@apferrer.com en aida-perez@apferrer-com.

Qué no cubre: Este patrón no valida si el dominio existe realmente ni si la dirección está activa. Solo verifica que parezca un email. Para validación completa, necesitarías enviar un correo de confirmación o consultar un servicio de validación de emails.


Patrón 2: Teléfono español (móvil y fijo con +34)

Qué valida: Números españoles con o sin prefijo +34, móviles o fijos.

Patrón regex:

^(\+34|0034)?[ -]?[6789]\d{2}[ -]?[0-9]{3}[ -]?[0-9]{3}$

Desglose: Comienza (^), prefijo opcional ((\+34|0034)?), espacios o guiones opcionales ([ -]?), primer dígito 6-9 (móvil o fijo), seguido de dos dígitos, espacios/guiones opcionales, 3 dígitos, espacios/guiones opcionales, 3 dígitos finales, termina ($).

Ejemplos válidos:

  • +34 666 123 456
  • 666123456
  • +34-666-123-456
  • 934 123 456 (fijo Barcelona)
  • 0034 912 345 678

Ejemplos inválidos:

  • +34 566 123 456 (el 5 no es válido para inicio)
  • +34 66 123 456 (faltan dígitos: solo 8 en total)
  • 666-12-345 (estructura de dígitos incorrecta)

Casos de uso reales:

  1. Centro de Salud Rural recibe citas por un formulario web. La regex valida teléfono de contacto para evitar agendar con números incompletos. Acepta variantes porque los pacientes escriben de formas distintas: con prefijo, sin él, con espacios o sin.

  2. Agencia de Aduanas integra datos de clientes desde terceros. Necesita normalizar: algunos envían +34 666 111 222, otros 666111222. La regex los identifica como válidos antes de procesarlos.

  3. Call Center de Seguros valida teléfonos entrantes. Rechaza números que comienzan con 5 (no son españoles válidos) y marca en rojo aquellos sin suficientes dígitos.

Variantes según rigidez:

  • Más flexible (acepta más espacios): ^[\s\-\+\d()]+$ y luego cuentas dígitos (muy permisivo)
  • Actual (recomendado): El patrón de arriba
  • Más estricto (sin prefijo): ^[6789]\d{8}$ (solo móvil/fijo sin prefijo, sin espacios)

Falsos positivos y negativos:

  • Falso positivo: +34 699 111 222 se acepta (correcto, es válido).
  • Falso negativo: +34 (666) 123 456 se rechaza porque no contempla paréntesis. Si necesitas soportar paréntesis, añade: (\(|\))? a la clase de caracteres.
  • Falso positivo: +34 877 123 456 se acepta si tu patrón incluye 8 (es fijo válido, pero en Cataluña). Revisión: 8 es válido para Barcelona, eso es correcto.

En Google Sheets:

=REGEXMATCH(A1,"^(\+34|0034)?[ -]?[6789]\d{2}[ -]?[0-9]{3}[ -]?[0-9]{3}$")

Para extraer solo los dígitos y descartar prefijo:

=REGEXEXTRACT(A1,"([6789]\d{2}[ -]?[0-9]{3}[ -]?[0-9]{3})$")

Devuelve 666 123 456 desde +34 666 123 456.

Qué no cubre: No valida si el número está activo, ni si el prefijo 666 pertenece a un operador real (Vodafone, Orange, Movistar, etc.). Solo verifica estructura. Para verdadera validación, necesitarías un servicio como TrueCaller API.


Patrón 3: IBAN español

Qué valida: Código IBAN español (ES + 22 caracteres numéricos, con estructura interna).

Patrón regex:

^ES\d{2}\d{4}\d{4}[\dA-Z]{1,4}\d{7}([A-Z]\d{3})?$

Desglose: Comienza con ES, dos dígitos de control, cuatro dígitos de banco, cuatro dígitos de sucursal, hasta 4 caracteres alfanuméricos, 7 dígitos de cuenta, opcionalmente una letra y 3 dígitos.

Ejemplos válidos:

  • ES9121000418450200051332
  • ES1234567890123456789012

Ejemplos inválidos:

  • ES9121000418450200 (incompleto: faltan dígitos)
  • GB9121000418450200051332 (comienza con GB, no ES)
  • ES912100041845020005 (muy corto)

Casos de uso reales:

  1. Plataforma de Pagos B2B recibe IBANs de proveedores antes de hacer transferencias. Esta regex rechaza formatos inválidos en el formulario, evitando rechazos bancarios posteriores que cuesta dinero reintentar.

  2. Gestoría Digital importa datos de clientes desde archivos CSV. Usa regex para marcar IBANs que no cumplen estructura, antes de pasarlos al sistema de contabilidad.

  3. Fintech de Nóminas valida IBAN de trabajadores. Rechaza caracteres no permitidos y longitud incorrecta, reduciendo errores al cargar masivamente.

Variantes según rigidez:

  • Más flexible (solo estructura general): ^ES\d{22}$ (solo comprueba ES + 22 dígitos)
  • Actual (recomendado): El patrón de arriba
  • Más estricto (con validación mod-97): Requiere Apps Script en Sheets, no solo regex

Falsos positivos y negativos:

  • Falso positivo: ES1234567890123456789012 se acepta (cumple formato, aunque podría no existir como cuenta real).
  • Falso negativo: es9121000418450200051332 (minúsculas) se rechaza si tu patrón exige mayúsculas. Solución: ^[Ee][Ss] o usar bandera i.

En Google Sheets:

=REGEXMATCH(A1,"^ES\d{2}\d{4}\d{4}[\dA-Z]{1,4}\d{7}([A-Z]\d{3})?$")

Para extraer el número de cuenta (últimos 7 dígitos):

=REGEXEXTRACT(A1,"(\d{7})$")

Devuelve 0051332 desde ES9121000418450200051332.

Qué no cubre: Este patrón no valida el dígito de control IBAN (requiere algoritmo mod-97, que es matemático, no regex). Es validación de formato. Para validación completa, necesitarías una función personalizada en Apps Script que implemente el algoritmo mod 97.


Patrón 4: Código postal español

Qué valida: 5 dígitos, rango real 01000-52999 (provincias españolas válidas).

Patrón regex:

^(?:0[1-9]|[1-4]\d|5[0-2])\d{3}$

Desglose: Comienza con 0 y 1-9 (01-09), o 1-4 y cualquier dígito (10-49), o 5 y 0-2 (50-52), seguido de 3 dígitos. Esto restringe a 01000-52999, que son los códigos postales válidos en España.

Ejemplos válidos:

  • 28001 (Madrid)
  • 08002 (Barcelona)
  • 41001 (Sevilla)
  • 46001 (Valencia)
  • 52001 (Melilla)

Ejemplos inválidos:

  • 99001 (superior a 52, no existe provincia)
  • 00123 (00 no es válido)
  • 1234 (solo 4 dígitos)

Casos de uso reales:

  1. E-commerce de Ropa valida código postal al procesar envíos. Rechaza códigos fuera del rango español para evitar envíos a direcciones fraudulentas o mal introducidas.

  2. Empresa de Logística recibe datos de almacenes regionales. Usa esta regex para agrupar por provincia (primer dígito) y detectar erratas en códigos.

  3. App de Delivery limita zona de reparto. Valida que el código postal esté en su ámbito de operación, rechazando entregas fuera de cobertura.

Variantes según rigidez:

  • Más flexible (solo 5 dígitos): ^\d{5}$ (acepta todo, incluso códigos no españoles)
  • Actual (recomendado): El patrón de arriba
  • Más estricto (por provincia exacta): ^(0[1-9]|[1-4][0-9]|5[0-2])\d{3}$ (igual, pero más legible)

Falsos positivos y negativos:

  • Falso positivo: 52001 se acepta (Melilla, válido).
  • Falso negativo: 052001 (con cero delante) se rechaza si no contemplas ese caso.
  • Falso positivo: 50999 se acepta (Zaragoza, válido).

En Google Sheets:

=REGEXMATCH(A1,"^(?:0[1-9]|[1-4]\d|5[0-2])\d{3}$")

Para extraer la provincia (primeros 2 dígitos):

=REGEXEXTRACT(A1,"^(\d{2})")

Devuelve 28 desde 28001.

Qué no cubre: No verifica si ese código postal existe realmente en España, solo que el rango sea válido. Por ejemplo, 28001 es formato válido (Madrid), pero no todas las combinaciones existen. Para verdadera validación, necesitarías una base de datos de códigos postales reales.


Patrón 5: DNI español

Qué valida: 8 dígitos + letra con formato correcto (no valida matemática de la letra).

Patrón regex (solo formato, sin validación de letra):

^\d{8}[TRWAGMYFPDXBNJZSQVHLCKE]$

Desglose: 8 dígitos exactos, seguidos de una de las 23 letras válidas para DNI español (el conjunto completo de letras permitidas por la Dirección General de la Policía).

Ejemplos válidos (formato):

  • 12345678Z
  • 98765432T
  • 11111111A

Ejemplos inválidos:

  • 12345678A (la A no está en el conjunto válido para DNI)
  • 1234567Z (solo 7 dígitos)
  • 123456789Z (9 dígitos)

Casos de uso reales:

  1. Clínica Privada registra pacientes por teléfono. La regex valida DNI mientras la recepcionista anota, rechazando letras inválidas antes de guardar en base de datos.

  2. Banco Online comprueba DNI al abrir cuenta. Aunque no valida la letra matemáticamente, rechaza formatos obvios como 12345678@ (símbolo inválido).

  3. Notaría Digital importa datos de clientes desde terceros. Usa regex para marcar filas sospechosas: si hay 8 dígitos pero una letra inválida, la humano lo revisa.

Variantes según rigidez:

  • Más flexible (sin validar letras): ^\d{8}[A-Z]$ (acepta cualquier letra mayúscula)
  • Actual (recomendado): El patrón de arriba (solo letras válidas)
  • Más estricto (con validación de letra): Requiere Apps Script con algoritmo mod 23

Falsos positivos y negativos:

  • Falso positivo: 12345678Z se acepta (formato correcto, aunque podría no corresponder a esa persona real).
  • Falso negativo: 12345678a (letra minúscula) se rechaza. Solución: Añade (?i) al inicio para ignorar mayúsculas, o convierte a mayúsculas antes.
  • Falso negativo: 12.345.678Z (con puntos) se rechaza. Algunos ciudadanos los escriben así.

En Google Sheets:

=REGEXMATCH(A1,"^\d{8}[TRWAGMYFPDXBNJZSQVHLCKE]$")

Para extraer solo los dígitos:

=REGEXEXTRACT(A1,"^(\d{8})")

Devuelve 12345678 desde 12345678Z.

Para validar si la letra es correcta (necesita Apps Script):

=REGEXMATCH(A1,"^\d{8}[TRWAGMYFPDXBNJZSQVHLCKE]$") * (MOD(VALUE(LEFT(A1,8)),23) = FIND(RIGHT(A1,1),"TRWAGMYFPDXBNJZSQVHLCKE")-1)

Esta fórmula es compleja; mejor usa Apps Script.

Qué no cubre: Este patrón verifica que la letra esté en el conjunto válido, pero no calcula si la letra es la correcta para esos 8 dígitos específicos. El algoritmo correcto es: divide los 8 dígitos por 23, el resto te da la posición en la cadena de letras válidas. Para validación completa, necesitarías Apps Script con esa lógica.


Patrón 6: NIE español

Qué valida: Número de Identidad de Extranjero (X, Y o Z + 7 dígitos + letra válida).

Patrón regex:

^[XYZ]\d{7}[TRWAGMYFPDXBNJZSQVHLCKE]$

Desglose: Comienza con X, Y o Z (letras de categoría NIE), seguido de 7 dígitos (9 dígitos en total), termina con una letra válida de NIE (mismo conjunto que DNI).

Ejemplos válidos (formato):

  • X1234567L
  • Y9876543M
  • Z0000001T

Ejemplos inválidos:

  • A1234567L (comienza con A, debe ser X, Y o Z)
  • X123456L (solo 6 dígitos, faltan dígitos)
  • X12345678L (9 dígitos, demasiados)

Casos de uso reales:

  1. Oficina de Extranjería registra solicitudes. La regex valida NIE en tiempo real mientras la oficinista lo anota, previniendo errores tipográficos.

  2. Empresa de Recursos Humanos valida NIE de trabajadores extranjeros. Rechaza formatos inválidos antes de inscribir en Seguridad Social.

  3. Gestoría Fiscal importa datos de clientes extranjeros. Marca NIE sospechosos para revisión manual si no cumplen patrón.

Variantes según rigidez:

  • Más flexible (sin validar letras): ^[XYZ]\d{7}[A-Z]$
  • Actual (recomendado): El patrón de arriba
  • Más estricto (con validación de letra): Requiere algoritmo, similar a DNI

Falsos positivos y negativos:

  • Falso positivo: X1234567L se acepta (formato correcto).
  • Falso negativo: x1234567l (minúsculas) se rechaza. Solución: Convierte a mayúsculas o usa bandera i.
  • Falso negativo: X-1234567-L (con guiones) se rechaza si no contemplas separadores.

En Google Sheets:

=REGEXMATCH(A1,"^[XYZ]\d{7}[TRWAGMYFPDXBNJZSQVHLCKE]$")

Para extraer la letra inicial:

=REGEXEXTRACT(A1,"^([XYZ])")

Devuelve X desde X1234567L.

Qué no cubre: Como el DNI, no valida si la letra es la correcta matemáticamente. Solo verifica que esté en el conjunto válido. La validación matemática de NIE usa el mismo algoritmo mod 23 que DNI.


Patrón 7: Matrícula española (formato actual y anterior)

Qué valida: Placa de vehículo española actual (4 números + 3 letras) o anterior (2 letras + 4 números + 2 letras).

Patrón regex (formato actual):

^[0-9]{4}[A-Z]{3}$

Patrón regex (formato anterior):

^[A-Z]{2}[0-9]{4}[A-Z]{2}$

Patrón regex (ambos formatos combinados):

^(?:[0-9]{4}[A-Z]{3}|[A-Z]{2}[0-9]{4}[A-Z]{2})$

Desglose (combinado): Grupo no capturador con alternancia: o bien 4 dígitos + 3 letras (actual), o bien 2 letras + 4 dígitos + 2 letras (anterior).

Ejemplos válidos:

  • 1234ABC (actual)
  • AB1234CD (anterior)
  • 5678XYZ (actual)
  • ZZ9999LL (anterior)

Ejemplos inválidos:

  • 123ABC (incompleto: solo 3 dígitos)
  • 1234ABCD (exceso: 4 letras)
  • AB123CD (anterior, pero solo 3 dígitos)

Casos de uso reales:

  1. Taller Mecánico Online recibe solicitudes de mantenimiento por formulario. Valida matrícula antes de agendar, rechazando tipografías que puedan causar confusión.

  2. App de Parkings recibe matrículas de usuarios que entran. Rechaza formatos inválidos para evitar registrar vehículos ficticios.

  3. Gestoría de Tráfico importa datos de multas. Usa regex para marcar matrículas sospechosas que no cumplen formato real, antes de enviar avisos.

Variantes según rigidez:

  • Más flexible (sin separar formatos): ^[A-Z0-9]{7}$ (acepta cualquier combinación de 7 caracteres)
  • Actual (recomendado): El combinado arriba
  • Más estricto (actual solo): ^[0-9]{4}[A-Z]{3}$ (rechaza matrículas antiguas)

Falsos positivos y negativos:

  • Falso positivo: 1234ABC se acepta (formato actual válido).
  • Falso negativo: 1234 ABC (con espacio) se rechaza. Algunos sistemas insertan espacios. Solución: ^(?:[0-9]{4} ?[A-Z]{3}|[A-Z]{2} ?[0-9]{4} ?[A-Z]{2})$
  • Falso negativo: 1234abc (letras minúsculas) se rechaza si exiges mayúsculas.

En Google Sheets (ambos formatos):

=REGEXMATCH(A1,"^(?:[0-9]{4}[A-Z]{3}|[A-Z]{2}[0-9]{4}[A-Z]{2})$")

Para extraer los dígitos numéricos:

=REGEXEXTRACT(A1,"([0-9]{4})")

Devuelve 1234 desde 1234ABC o AB1234CD.

Para determinar si es formato actual o anterior:

=IF(REGEXMATCH(A1,"^[0-9]{4}[A-Z]{3}$"),"Actual","Anterior")

Qué no cubre: No verifica si la matrícula está activa o registrada en la DGT (Dirección General de Tráfico). Solo verifica estructura. Para validación real, necesitarías consultar la base de datos de la DGT o un servicio externo.


Patrón 8: Fecha en formato dd/mm/yyyy

Qué valida: Fechas en formato español (día/mes/año) con controles básicos de rango (día 01-31, mes 01-12).

Patrón regex:

^(0[1-9]|[12]\d|3[01])/(0[1-9]|1[0-2])/\d{4}$

Desglose: Día válido (01-31), barra, mes válido (01-12), barra, 4 dígitos de año. No valida años bisiestos ni meses con 30 días.

Ejemplos válidos:

  • 15/06/2026
  • 01/01/2000
  • 31/12/1999
  • 29/02/2020 (año bisiesto, pero el patrón no lo comprueba)

Ejemplos inválidos:

  • 32/13/2026 (día 32 y mes 13 no existen)
  • 0/1/2026 (faltan ceros a la izquierda)
  • 15-06-2026 (guiones en lugar de barras)

Casos de uso reales:

  1. Plataforma de Citas Médicas valida fecha de nacimiento. Rechaza fechas con día 32 o mes 13, evitando inscripciones inválidas antes de guardarse.

  2. App de Eventos recibe fechas de eventos. Valida formato dd/mm/yyyy para asegurar coherencia con usuarios españoles.

  3. Sistema de Facturación valida fecha de emisión. Rechaza formatos inconsistentes, garantizando que todos los datos guardados sean legibles.

Variantes según rigidez:

  • Más flexible (sin separador específico): ^\d{2}[/-]\d{2}[/-]\d{4}$ (acepta barras o guiones)
  • Actual (recomendado): El patrón de arriba (solo barras)
  • Más estricto (con validación de bisiesto): Requiere lógica adicional en Apps Script

Falsos positivos y negativos:

  • Falso positivo: 31/12/2026 se acepta (aunque diciembre tiene 31 días, es correcto).
  • Falso positivo: 29/02/1900 se acepta (pero 1900 no fue bisiesto; el patrón no lo comprueba).
  • Falso negativo: 29/02/2020 se acepta (año bisiesto real, es correcto).
  • Falso negativo: 31/04/2026 se acepta (abril tiene 30 días, pero el patrón no lo comprueba).

En Google Sheets:

=REGEXMATCH(A1,"^(0[1-9]|[12]\d|3[01])/(0[1-9]|1[0-2])/\d{4}$")

Para extraer solo el año:

=REGEXEXTRACT(A1,"(\d{4})$")

Devuelve 2026 desde 15/06/2026.

Para reemplazar barras por guiones:

=REGEXREPLACE(A1,"/","-")

Convierte 15/06/2026 en 15-06-2026.

Para validar que no sea una fecha futura (requiere lógica adicional):

=AND(REGEXMATCH(A1,"^(0[1-9]|[12]\d|3[01])/(0[1-9]|1[0-2])/\d{4}$"), DATEVALUE(A1) <= TODAY())

Qué no cubre: Este patrón no valida si la fecha existe realmente (por ejemplo, 29/02 en años no bisiestos, o 31/04 cuando abril tiene 30 días). Solo valida rango básico de día y mes. Para verdadera validación, necesitarías una función que analice el mes y el año.


Debuggeando regex que no funcionan

Has copiado un patrón, lo probaste en regex101, pero en Sheets o en tu código no funciona. Aquí están los 6 problemas más comunes y cómo resolverlos.

Problema 1: Caracteres sin escapar

Un punto . en regex significa "cualquier carácter". Si quieres un punto literal, debes escaparlo: \..

Síntoma: Tu patrón de email ^[a-z]+@[a-z]+.[a-z]+$ acepta aida@example!com (! no es punto, pero . lo acepta).

Solución: Escapa todos los caracteres especiales: ^[a-z]+@[a-z]+\.[a-z]+$.

Otros caracteres a escapar: * + ? [ ] ( ) { } | ^ $ \ (cuando quieres literal, no especial).

Problema 2: Confundir * y +

* permite cero repeticiones, + requiere al menos una.

Síntoma: Tu patrón [a-z]*@[a-z]+ acepta @dominio.com (cero caracteres antes del @, que no es válido).

Solución: Usa + para "al menos uno": [a-z]+@[a-z]+.

Regla: Si necesitas al menos un carácter, usa +. Si cero es válido (ej. sufijo opcional), usa *.

Problema 3: Olvidar anclas

Sin ^ y $, el patrón puede coincidir en cualquier parte de la cadena.

Síntoma: Tu patrón \d{8}[A-Z] sin anclas coincide con "abc12345678Zxyz", extrayendo 12345678Z del medio (probablemente no es lo que querías).

Solución: Añade anclas: ^\d{8}[A-Z]$.

Esto garantiza que toda la cadena coincida, no solo una parte.

Problema 4: No escapar o mal colocar guiones en clases

En [a-z], el guion conecta un rango. En [a-z.-], ¿el guion es rango o literal?

Síntoma: Tu patrón [a-zA-Z.-] se interpreta como rango de . a - (caracteres ASCII 46-45, que no existe).

Solución: Coloca el guion al final [a-zA-Z.-] o escapado [a-zA-Z\.-].

Correcto: [a-zA-Z.-] funciona (guion al final es literal) o [a-zA-Z\.\-] (escapados).

Problema 5: Confundir REGEXMATCH, REGEXEXTRACT, REGEXREPLACE en Sheets

  • REGEXMATCH(texto, patrón) devuelve VERDADERO/FALSO
  • REGEXEXTRACT(texto, patrón) devuelve el texto que coincide
  • REGEXREPLACE(texto, patrón, sustitución) reemplaza

Síntoma: Escribes =REGEXMATCH(A1, "[0-9]+") esperando obtener los dígitos, pero solo obtienes VERDADERO.

Solución: Usa REGEXEXTRACT: =REGEXEXTRACT(A1, "[0-9]+") devuelve los dígitos encontrados.

Problema 6: Diferenciar mayúsculas/minúsculas cuando no debería

Por defecto, regex es sensible a mayúsculas.

Síntoma: Tu patrón ^[a-z]+$ rechaza "Aida" (tiene mayúscula A).

Solución: Incluye mayúsculas en la clase: ^[a-zA-Z]+$. O usa flag i (insensible): algunos entornos soportan /patrón/i.

En Sheets, no hay flag directo, así que incluye ambas: [a-zA-Z].


Tabla comparativa final: qué cubre, qué no cubre, alternativas

Patrón Qué valida Qué NO cubre Cuándo falla Alternativa si necesitas más
Email Formato usuario@dominio.ext Dominio existente, cuenta activa test@nonexistent.fake se acepta Servicio de validación de email (NeverBounce, ZeroBounce)
Teléfono ES Estructura +34/0034, 9 dígitos Número activo, operador real +34 999 999 999 se acepta (podría no existir) API de validación de telefonía (Twilio Lookup)
IBAN ES Estructura ES + 22 chars Dígito de control (mod-97), cuenta real ES1234567890123456789012 se acepta (podría no existir) Apps Script con algoritmo mod-97, o servicio IBAN API
Código postal Rango 01000-52999 Código postal real, existente 28999 se acepta (fuera de rango válido de Madrid) Base de datos de códigos postales españoles reales
DNI 8 dígitos + letra válida Letra correcta (mod 23), DNI real 12345678Z se acepta (letra podría ser incorrecta) Apps Script con validación mod 23, o consulta BD registral
NIE X/Y/Z + 7 dígitos + letra válida Letra correcta (mod 23), NIE real X1234567L se acepta (letra podría ser incorrecta) Apps Script con validación mod 23, o consulta BD inmigración
Matrícula Formato actual (4+3) o anterior (2+4+2) Matrícula activa, registrada en DGT 1234ABC se acepta (podría no estar registrada) Consulta DGT API, o servicio de búsqueda de matrículas
Fecha Formato dd/mm/yyyy, rango día/mes Año bisiesto, días por mes reales 31/04/2026 se acepta (abril tiene 30) Función DATE nativa en Sheets o Apps Script con validación

Errores frecuentes al copiar regex de internet

1. Caracteres sin escapar. Un punto . en regex significa "cualquier carácter". Si quieres un punto literal, debes escaparlo: \.. El patrón de email lo hace bien con \.[a-zA-Z]{2,}.

2. Confundir * y +. * permite cero repeticiones, + requiere al menos una. En email, [a-zA-Z0-9]+@ es correcto porque necesitas al menos un carácter antes del @. Con * aceptarías @dominio.com, que no es válido.

3. Olvidar anclas. Sin ^ y $, el patrón puede coincidir en cualquier parte de la cadena. \d{8}[A-Z] sin anclas coincide con "abc12345678Zxyz", lo que probablemente no quieres.

4. No escapar el guion en clases. En [a-zA-Z.-], el guion debe estar al final o escapado [a-zA-Z\.-], si no, se interpreta como rango.

5. Confundir REGEXMATCH con REGEXEXTRACT. En Sheets:

  • REGEXMATCH(texto, patrón) devuelve VERDADERO/FALSO
  • REGEXEXTRACT(texto, patrón) devuelve el texto que coincide
  • REGEXREPLACE(texto, patrón, sustitución) reemplaza lo que coincide

6. No considerar variantes tipográficas. Usuarios escriben +34 666 123 456, 666123456, +34-666-123-456. Un patrón estricto rechaza válidos. Solución: permite espacios y guiones opcionales: [ -]?.


Copiar y pegar sin miedo

Cada patrón arriba está listo para copiar. Antes de usarlo:

  1. Abre regex101.com.
  2. Pega el patrón en la caja de arriba.
  3. Elige PCRE2 en el selector de la izquierda.
  4. Escribe tres ejemplos válidos y tres inválidos en la caja de texto.
  5. Verifica que regex101 marque los válidos en verde y los inválidos sin marcar.
  6. Copia el patrón a tu Sheets o código.

Si algo falla, regex101 te muestra exactamente dónde. No hay sorpresas al pasar a producción.


La trampa de "perfección"

Ninguno de estos patrones es perfecto. El de email no verifica que el dominio exista. El de DNI no calcula la letra. El de fecha no sabe qué es un año bisiesto.

Eso no es un fallo: es por diseño. Regex es una herramienta para validación de formato, no para verdad absoluta. Si necesitas verdad absoluta (¿existe este email? ¿este DNI es real? ¿esta fecha es válida en febrero?), necesitas un servicio externo, una base de datos, o una función con lógica matemática.

Lo que regex hace bien es rechazar lo obvio: un DNI con 7 dígitos, una matrícula con letras en el lugar de números, un email sin arroba. Y eso resuelve el 95% de los errores de entrada.


Siguiente paso

Estos ocho patrones cubren la mayoría de los datos que recoges en España. Ahora tienes dos caminos.

Si quieres automatizar validación en Sheets, mira el artículo sobre trucos de Google Sheets donde usamos REGEXMATCH en cascadas de validación.

Si quieres ir más allá y construir herramientas propias, reserva una sesión para hablar de cómo automatizar tus procesos de datos sin código o con código mínimo.


Referencias

AF
APFerrer
APFerrer · Consultora en datos y procesos
Nota de la autora

¿Aplica a tu empresa? Cuéntamelo en 30 minutos y vemos qué encaja.

Reservar 30 min