Validar direcciones IPv4 con expresiones regulares

Resuelto Matthieu Cartier asked hace 13 años • 47 respuestas

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í.

Matthieu Cartier avatar Mar 13 '11 00:03 Matthieu Cartier
Aceptado

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 \den 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-99casos. 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, 0números iniciales y una IP que termina con una.

Danail Gabenski avatar Apr 21 '2016 05:04 Danail Gabenski

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'
    ^                                    ^
Mark Byers avatar Mar 12 '2011 18:03 Mark Byers
^((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

Enginer avatar Sep 22 '2014 07:09 Enginer