Regex para direcciones IPv4: de 0 a 255 como es debido
Una dirección IPv4 son cuatro números de 0 a 255. Por qué el patrón obvio con \d{1,3} deja pasar 999.999.999.999, cómo describir un octeto con alternancia, qué hacer con los ceros a la izquierda y cómo encontrar direcciones dentro de un texto.

· 7 min de lectura · Actualizado el
/^(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)$/
atrapa
- 0
- 42
- 199
- 255
deja libre
- 256
- 300
- 07
- 1000
Una dirección IPv4 son cuatro números separados por puntos, como 192.168.1.1. Cada número se llama octeto y va de 0 a 255.
Parece fácil de reconocer, y el primer patrón que escribe casi todo el mundo es corto y está mal. Este artículo empieza por ahí, lo corrige paso a paso y termina con un patrón para encontrar direcciones dentro de un texto. Todos los ejemplos son interactivos, así que edita los patrones y mira cómo cambian las líneas.
/^ ( (25[0-5]| 2[0-4]\d| 1\d\d| [1-9]?\d) \.){3} (25[0-5]| 2[0-4]\d| 1\d\d| [1-9]?\d)$/Cuatro números del 0 al 255 separados por puntos, sin ceros a la izquierda.
Acepta
- 192.168.1.1
- 10.0.0.1
- 255.255.255.0
Rechaza
- 256.1.1.1
- 010.0.0.1
- 1.2.3
01El patrón obvio
Cuatro grupos de uno a tres dígitos, separados por puntos:
/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/Debe coincidir4/4
- 192.168.1.1
- 8.8.8.8
- 999.999.999.999
- 300.1.2.3
No debe2/2
- 1.2.3
- 1.2.3.4.5
Sí detecta un número incorrecto de partes. Y si estás revisando logs de confianza, puede que no necesites más. Pero como validador acepta cualquier cosa hasta 999.
La repetición puede ser más corta. Tres octetos terminan en punto, así que agrupa “octeto más punto” y repítelo tres veces con {3}:
/^(\d{1,3}\.){3}\d{1,3}$/02No olvides la barra invertida
En un patrón, un . suelto significa “cualquier carácter”. Quita las barras invertidas y los puntos dejan de significar puntos:
1234567 es la más traicionera. Cada . coincide con un dígito, así que el patrón la lee como 1, 3, 5, 7 con 2, 4, 6 haciendo de “puntos”.
03Un octeto, de 0 a 255
Una regex no tiene ni idea de lo que vale un número. Solo ve caracteres. Así que “de 0 a 255” hay que escribirlo como reglas de texto, dividido en rangos que tengan cada uno una forma sencilla:
| Rango | Patrón | Se lee como |
|---|---|---|
| 250–255 | 25[0-5] |
25, luego de 0 a 5 |
| 200–249 | 2[0-4]\d |
2, luego de 0 a 4, luego cualquier dígito |
| 100–199 | 1\d\d |
1, luego dos dígitos cualesquiera |
| 0–99 | [1-9]?\d |
un 1 a 9 opcional, luego cualquier dígito |
Únelos con | y mételos en un grupo:
/^(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)$/Debe coincidir6/6
- 0
- 9
- 42
- 199
- 249
- 255
No debe4/4
- 256
- 300
- 07
- 1000
04Ceros a la izquierda
Fíjate en la última rama: [1-9]?\d, no \d{1,2}. Eso es lo que rechaza 07 y 010. Un octeto de dos dígitos tiene que empezar por 1 a 9.
Esto importa más de lo que parece. Algunas herramientas leen un cero a la izquierda como un número en octal. socket.inet_aton de Python, que sigue las antiguas reglas de red de C, convierte 010.0.0.1 en 8.0.0.1, porque 10 en octal es 8. Si una parte de tu sistema lee 010 como diez y otra como ocho, no se ponen de acuerdo sobre de qué dirección hablan. Rechazar los ceros a la izquierda evita la cuestión por completo.
05El patrón completo
Pon el grupo del octeto donde antes estaba \d{1,3}:
/^((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)\.){3}(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)$/Debe coincidir4/4
- 0.0.0.0
- 10.0.0.1
- 192.168.1.1
- 255.255.255.0
No debe6/6
- 256.1.1.1
- 192.168.1.300
- 999.999.999.999
- 010.0.0.1
- 1.2.3
- 1.2.3.4.5
Es largo, pero es largo porque el octeto aparece dos veces, no porque sea complicado. Esto es lo que ahorra el {3} frente a escribir el octeto cuatro veces:
Tablero0.0.0.0 · 10.0.0.1 · 192.168.1.1 · 255.255.255.0 · 8.8.4.4 vs 256.1.1.1 · 10.0.0 · 1.2.3.4.5 · 192.168.1.300 · 010.0.0.1
- escrito enterolo resuelve140
/^(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)$/ - con un grupolo resuelve75
/^((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)\.){3}(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)$/
06Encontrar direcciones dentro de un texto
^ y $ solo sirven cuando toda la entrada es una dirección. Para encontrar direcciones en una línea de log, lo habitual es cambiarlos por límites de palabra, \b. Casi funciona:
/\b((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)\.){3}(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)\b/Debe coincidir2/2
- server at 10.0.0.1.
- version 1.2.3.4.5
No debe1/1
- error 999.1.1.1
Lo que de verdad quieres es “ningún dígito ni punto justo antes, y nada más de dirección justo después”. Eso es trabajo para los lookarounds:
/(?<![\d.])((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)\.){3}(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?!\.?\d)/Debe coincidir2/2
- server at 10.0.0.1.
- ping 8.8.8.8 now
No debe3/3
- version 1.2.3.4.5
- error 999.1.1.1
- build 1.2.3
Este también funciona con el re de Python. Python solo admite lookbehind de ancho fijo, y (?<![\d.]) siempre comprueba exactamente un carácter.
07O usa un parser
Si estás validando entradas en código, la biblioteca estándar ya lo hace. En Python:
import ipaddress
ipaddress.ip_address("192.168.1.1") # IPv4Address('192.168.1.1')
ipaddress.ip_address("192.168.1.1").is_private # True
ipaddress.ip_address("256.1.1.1") # ValueError
Desde Python 3.9.5, ipaddress también rechaza ceros a la izquierda como 010.0.0.1. En Node, net.isIPv4("010.0.0.1") también es false, y da las mismas respuestas que el patrón completo de arriba en todos los ejemplos de este artículo. Un parser además se ocupa de IPv6, que es una regex mucho más grande.
08Pruébalo
El corazón de todo el patrón es el octeto. ¿Puedes escribirlo de memoria?
Atrapa los números de 0 a 255 y deja libre todo lo demás.
Objetivos · 0/10 atrapados
- 0objetivo
- 7objetivo
- 42objetivo
- 99objetivo
- 100objetivo
- 199objetivo
- 200objetivo
- 249objetivo
- 250objetivo
- 255objetivo
Inocentes · 0 errores
- 256inocente
- 260inocente
- 300inocente
- 999inocente
- 1000inocente
- 07inocente
- 007inocente
Escribe una regex: el tablero se actualiza mientras escribes.
09Lista de comprobación
\d{1,3}admite de 0 a 999. Usa(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)para un octeto.- Escapa todos los puntos:
\.. - Repite con un grupo:
(octet\.){3}octet. - Usa
[1-9]?\dpara los números pequeños, así se rechazan los ceros a la izquierda. - Dentro de un texto, usa
(?<![\d.])y(?!\.?\d)en lugar de\b. - En código, mejor
ipaddress(Python) onet.isIPv4(Node).
10Sigue practicando
- La sección de alternancia de la guía explica el
|con el que se construye el octeto. - Prueba la caza de hoy o repasa tableros anteriores en el archivo.