Patrones para validar campos
Un código postal con cuatro cifras, un móvil con una letra, un DNI sin letra: el formulario los acepta si no le dices cómo tienen que ser.
pattern da la forma que tiene que tener el valor entero; title la explica y required impide dejarlo vacío.
Grupos [ ], repeticiones {n}, +, *, ?, grupos ( ) y alternativas | cubren casi todos los campos.
Dentro de corchetes el guion se escapa (\-); fuera, no.
Para correo, web, fecha, hora o color, mejor el type que corresponde.
- Un código postal con cuatro cifras, un móvil con una letra, un DNI sin letra: el formulario los acepta si no le dices cómo tienen que ser. El atributo pattern le da al navegador la forma que tiene que tener el dato, con una expresión regular, y el navegador no deja enviar el formulario hasta que se cumple.
- <label for="cp">Código postal</label> <input id="cp" name="cp" inputmode="numeric" pattern="[0-9]{5}" title="Cinco cifras, por ejemplo 41001" required>
- pattern es la expresión regular. El navegador la compara con el valor entero: no hace falta marcar el principio ni el final. title explica el formato. El navegador lo enseña en el mensaje de error. Un campo vacío no se comprueba con pattern: para que sea obligatorio, required. El aspecto de error del campo se da con CSS (:user-invalid): lo ves en Formularios y tablas con CSS.
- PiezaQué significaEjemploVale abcEsas letras, tal cualESES [0-9]Un carácter de ese grupo[0-9]7 [A-Za-z]Una letra (sin tildes ni ñ)[A-Za-z]Z, q [^0-9]Cualquiera menos esos[^0-9]a .Cualquier carácter.a, 7, # {5}Lo anterior, 5 veces[0-9]{5}41001 {2,20}Entre 2 y 20 veces[a-z]{2,20}luna {8,}8 o más veces.{8,}huellas2026 + * ?1 o más · 0 o más · 0 o 1[0-9]+3, 2026 ( )Agrupa(-[a-z]+)*-a-luna |O[0-9]{8}[A-Z]|[XYZ][0-9]{7}[A-Z]DNI o NIE \+ \.El signo tal cual (escapado)\+34+34
- Las tildes y la ñ no entran en [A-Za-z]: si las quieres, añádelas al grupo, [A-Za-zÁÉÍÓÚÜÑáéíóúüñ ] (con un espacio al final si se admiten espacios).
Introducción
Un código postal con cuatro cifras, un móvil con una letra, un DNI sin letra: el formulario los acepta si no le dices cómo tienen que ser. El atributo pattern le da al navegador la forma que tiene que tener el dato, con una expresión regular, y el navegador no deja enviar el formulario hasta que se cumple.
<label for="cp">Código postal</label> <input id="cp" name="cp" inputmode="numeric" pattern="[0-9]{5}" title="Cinco cifras, por ejemplo 41001" required>
pattern es la expresión regular. El navegador la compara con el valor entero: no hace falta marcar el principio ni el final. title explica el formato. El navegador lo enseña en el mensaje de error. Un campo vacío no se comprueba con pattern: para que sea obligatorio, required. El aspecto de error del campo se da con CSS (:user-invalid): lo ves en Formularios y tablas con CSS.
Las piezas
PiezaQué significaEjemploVale abcEsas letras, tal cualESES [0-9]Un carácter de ese grupo[0-9]7 [A-Za-z]Una letra (sin tildes ni ñ)[A-Za-z]Z, q [^0-9]Cualquiera menos esos[^0-9]a .Cualquier carácter.a, 7, # {5}Lo anterior, 5 veces[0-9]{5}41001 {2,20}Entre 2 y 20 veces[a-z]{2,20}luna {8,}8 o más veces.{8,}huellas2026 + * ?1 o más · 0 o más · 0 o 1[0-9]+3, 2026 ( )Agrupa(-[a-z]+)*-a-luna |O[0-9]{8}[A-Z]|[XYZ][0-9]{7}[A-Z]DNI o NIE \+ \.El signo tal cual (escapado)\+34+34
Las tildes y la ñ no entran en [A-Za-z]: si las quieres, añádelas al grupo, [A-Za-zÁÉÍÓÚÜÑáéíóúüñ ] (con un espacio al final si se admiten espacios).
⚠️ Atención. Los navegadores leen pattern en un modo estricto. Dentro de corchetes, el guion que es un carácter se escapa ([a-z0-9_\-]); fuera de corchetes va tal cual ((-[a-z0-9]+)*). Si escribes \- fuera de corchetes, el patrón deja de funcionar: el navegador lo ignora y solo avisa en la consola de las DevTools.
Construir un patrón paso a paso
Un móvil español: nueve cifras y la primera es un 6 o un 7.
La primera cifra, de un grupo de dos: [67]. Ocho cifras más: [0-9]{8}. Juntas: [67][0-9]{8}. Con el prefijo +34 opcional: el + se escapa, se agrupa y se marca como opcional, (\+34)?[67][0-9]{8}.
Pruébalo siempre con valores que sí tienen que valer y con otros que no: una cifra de menos, una de más, una letra en medio.
Ejemplos que vas a usar
CampopatternOjo Código postal (España)[0-9]{5}Solo la forma Móvil[67][0-9]{8}Fijos y móviles: [6-9][0-9]{8} DNI[0-9]{8}[A-Za-z]No comprueba la letra NIE[XYZxyz][0-9]{7}[A-Za-z] Matrícula[0-9]{4} ?[BCDFGHJKLMNPRSTVWXYZ]{3}Sin vocales, Ñ ni Q IBAN españolES[0-9]{22}Sin espacios Hora (24 h)([01][0-9]|2[0-3]):[0-5][0-9]Mejor type="time" Color#[0-9a-fA-F]{6}Para elegir, type="color" Usuario[a-z0-9_]{3,15} Dirección amigable[a-z0-9]+(-[a-z0-9]+)*adopta-a-luna
En una tabla de Markdown la barra | se escribe \|; en el HTML va sola.
Comprobar que algo aparece: (?=…)
Para una contraseña con al menos una mayúscula, una minúscula y una cifra, el orden da igual. (?=.*[A-Z]) comprueba que hay una mayúscula en alguna parte sin «gastar» ningún carácter; después, .{8,} pide la longitud:
Cuándo no usar pattern
Para correos y direcciones web hay type="email" y type="url", que ya validan. Para fechas, horas, números y colores, type="date", "time", "number" y "color" dan además un control para elegir. pattern comprueba la forma, no si el dato existe: un DNI con la letra mal o el 31 de febrero pasan. Eso se comprueba con JavaScript (lección Formularios con JavaScript) y, sobre todo, en el servidor.
Practica: «Laboratorio de patrones»
El laboratorio tiene un probador, las piezas para pulsar, los ejemplos de esta página listos para copiar y doce retos con los campos del formulario de adopción de un refugio de animales.
Errores frecuentes
Poner ^ y $: sobran, el navegador ya compara el valor entero. Usar pattern en un type="email": el tipo ya valida el correo. Olvidar title: el mensaje de error no dirá qué formato se espera. No probar valores que tienen que fallar: un patrón que lo acepta todo también «funciona».