Validar direcciones IPv4 con expresiones regulares
He estado intentando obtener una expresión regular eficiente para la validación de IPv4, pero sin mucha suerte. Parecía que en un momento lo había tenido (25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?(\.|$)){4}
, pero produce algunos resultados extraños:
$ grep --version
grep (GNU grep) 2.7
$ grep -E '\b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?(\.|$)){4}\b' <<< 192.168.1.1
192.168.1.1
$ grep -E '\b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?(\.|$)){4}\b' <<< 192.168.1.255
192.168.1.255
$ grep -E '\b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?(\.|$)){4}\b' <<< 192.168.255.255
$ grep -E '\b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?(\.|$)){4}\b' <<< 192.168.1.2555
192.168.1.2555
Hice una búsqueda para ver si esto ya se había preguntado y respondido, pero parece que otras respuestas simplemente muestran cómo determinar 4 grupos de 1 a 3 números, o no funcionan para mí.
Lo mejor para ahora ( 43 caracteres )
^((25[0-5]|(2[0-4]|1\d|[1-9]|)\d)\.?\b){4}$
Esta versión acorta las cosas en otros 6 caracteres sin utilizar la anticipación negativa, que no es compatible con algunos tipos de expresiones regulares.
Versión más nueva, más corta y menos legible ( 49 caracteres )
^((25[0-5]|(2[0-4]|1\d|[1-9]|)\d)(\.(?!$)|$)){4}$
Los [0-9]
bloques se pueden sustituir \d
en 2 lugares, lo que los hace un poco menos legibles, pero definitivamente más cortos.
Aún más nueva, incluso más corta, la segunda versión menos legible ( 55 caracteres )
^((25[0-5]|(2[0-4]|1[0-9]|[1-9]|)[0-9])(\.(?!$)|$)){4}$
Esta versión busca el caso 250-5, después de eso inteligentemente realiza OR todos los casos posibles para 200-249
100-199
10-99
casos. Tenga en cuenta que la |)
parte no es un error, sino que en realidad corresponde al último caso para el rango 0-9. También omití la ?:
parte del grupo de no captura ya que realmente no nos importan los elementos capturados, no serían capturados de ninguna manera si no tuviéramos una coincidencia completa en primer lugar.
Versión antigua y más corta (menos legible) ( 63 caracteres )
^(?:(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])(\.(?!$)|$)){4}$
Versión anterior (legible) ( 70 caracteres )
^(?:(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])(\.(?!$)|$)){4}$
Utiliza la búsqueda anticipada negativa (?!)
para eliminar el caso en el que la IP podría terminar con un.
Respuesta alternativa, utilizando algunas de las técnicas más nuevas ( 71 caracteres )
^((25[0-5]|(2[0-4]|1\d|[1-9]|)\d)\.){3}(25[0-5]|(2[0-4]|1\d|[1-9]|)\d)$
Útil en implementaciones de expresiones regulares donde no se admiten búsquedas anticipadas
Respuesta más antigua ( 115 caracteres )
^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}
(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])$
Creo que esta es la expresión regular más precisa y estricta, no acepta cosas como 000.021.01.0.
parece que hacen la mayoría de las otras respuestas aquí y requiere expresiones regulares adicionales para rechazar casos similares a ese, es decir, 0
números iniciales y una IP que termina con una.
Ya tiene una respuesta funcional, pero en caso de que tenga curiosidad sobre qué estaba mal con su enfoque original, la respuesta es que necesita paréntesis alrededor de su alternancia; de lo contrario, (\.|$)
solo se requiere si el número es menor que 200.
'\b((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.|$)){4}\b'
^ ^
^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$
Aceptar :
127.0.0.1
192.168.1.1
192.168.1.255
255.255.255.255
0.0.0.0
1.1.1.01 # This is an invalid IP address!
Rechazar :
30.168.1.255.1
127.1
192.168.1.256
-1.2.3.4
1.1.1.1.
3...3
Pruebe en línea con pruebas unitarias: https://www.debuggex.com/r/-EDZOqxTxhiTncN6/1