¿Cómo puedo hacer coincidir las direcciones IPv6 con una expresión regular de Perl?

StackOverflow https://stackoverflow.com/questions/1802722

  •  05-07-2019
  •  | 
  •  

Pregunta

Entonces necesito hacer coincidir una dirección ipv6 que puede o no tener una máscara. Lamentablemente, no puedo usar una biblioteca para analizar la cadena.

El bit de máscara es bastante fácil, en este caso:

(?:\/\d{1,3})?$/

La parte difícil son los diferentes formatos de una dirección ipv6. Debe coincidir con :: carne de res, carne de res ::, carne de res :: carne de res, etc.

Una actualización: ya casi estoy allí ..

/^(\:\:([a-f0-9]{1,4}\:){0,6}?[a-f0-9]{0,4}|[a-f0-9]{1,4}(\:[a-f0-9]{1,4}){0,6}?\:\:|[a-f0-9]{1,4}(\:[a-f0-9]{1,4}){1,6}?\:\:([a-f0-9]{1,4}\:){1,6}?[a-f0-9]{1,4})(\/\d{1,3})?$/i

Estoy, en este caso restringido a usar la expresión regular de perl.

¿Fue útil?

Solución

Esto contiene un parche para Regexp :: Demostración común una expresión regular IPv6 completa, precisa y probada. Es una traducción directa de la gramática IPv6. Regexp :: IPv6 también es precisa.

Más importante aún, contiene un conjunto de pruebas. Ejecutarlo con tu expresión regular muestra que todavía estás lejos. 10 de 19 fallados. 1 de cada 12 falsos positivos. IPv6 contiene muchas shorthands especiales que hacen que sea muy fácil equivocarse sutilmente.

El mejor lugar para leer lo que se incluye en una dirección IPv6 es la sección RFC 3986 3.2.2.

Otros consejos

¿Qué quieres decir con que no puedes usar una biblioteca? ¿Qué tal un módulo? Regexp :: IPv6 le dará lo que necesita .

No soy un experto en IPv6, pero confía en mí cuando te digo que hacer coincidir (y mucho menos validar) las direcciones IPv6 no es fácil con una expresión regular muy simple como la que sugieres. Hay muchas shorthands y varias convenciones para combinar la dirección con un puerto, solo por nombrar un ejemplo. Una de estas abreviaturas es que puedes escribir 0: 0: 0: 0: 0: 0: 0: 1 como :: 1, pero hay más. Si lees alemán, te sugiero que mires las diapositivas de la charla de Steffen Ullrich en el XI Taller Alemán de Perl.

Dices que no puedes usar una biblioteca, pero si vas a reinventar toda la complejidad de la biblioteca, también podrías importarla literalmente en tu proyecto.

Esto funciona principalmente ...

^([0-9a-fA-F]{0,4}|0)(\:([0-9a-fA-F]{0,4}|0)){7}$

Contras: :: los casos similares no se manejan correctamente

Prueba esto:

^([0-9a-fA-F]{4}|0)(\:([0-9a-fA-F]{4}|0)){7}$

De Biblioteca de expresiones regulares: dirección IPv6

También debería leer esto: Una expresión regular para direcciones IPv6

Si necesita comprobar en perl si una cadena es una dirección IPv6, puede probar esto:

if (/(([\da-f]{0,4}:{0,2}){1,8})/i) { print("$1") };

Prueba:

/^(((?=(?>.*?(::))(?!.+\3)))\3?|([\dA-F]{1,4}(\3|:(?!$)|$)|\2))(?4){5}((?4){2}|((2[0-4]|1\d|[1-9])?\d|25[0-5])(\.(?7)){3})\z/ai

De: http://home.deds.nl/~aeron/regex/

aquí está el que funcionó para todos los ejemplos de IPv6 que he logrado encontrar:

/^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((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)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((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)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((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)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((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)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((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)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((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)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((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)){3}))|:)))(%.+)?\s*$/

asegúrese de que sea una línea antes de usar. se ha encontrado aquí:

https: //community.helpsystems .com / forums / intermapper / misceláneo-temas / 5acc4fcf-fa83-e511-80cf-0050568460e4

verificado en todos los ejemplos de la página de preguntas, la página de la comunidad y el sitio de Wikipedia desde aquí:

https://en.wikipedia.org/wiki/IPv6

la herramienta para la verificación que se usa desde aquí:

https://regex101.com/

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top