2009-11-26 3 views
5

J'ai donc besoin de faire correspondre une adresse IPv6 qui peut ou non avoir un masque. Malheureusement, je ne peux pas utiliser une bibliothèque pour analyser la chaîne.Comment puis-je faire correspondre des adresses IPv6 avec une regex Perl?

Le bit de masque est assez facile, dans ce cas:

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

La partie difficile est les différents formats d'une adresse ipv6. Il doit correspondre à :: boeuf, boeuf ::, boeuf :: boeuf, etc.

Une mise à jour: Je suis presque ..

/^(\:\:([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 

Je suis, dans ce cas restreint aux années perl regex.

+1

Est-ce que ce sont les devoirs? Ou pourquoi ne pouvez-vous pas utiliser une bibliothèque et qu'est-ce qui vous fait dire que vous êtes limité à "perl's regex"? – innaM

+2

La langue que j'utilise est perl. Les changements nécessaires pour permettre l'utilisation d'autres bibliothèques seraient plus de travail. Définir les devoirs? Je suis à la maison et je travaille. C'est pour l'un des projets sur lesquels je travaille - si vous voulez dire à des fins éducatives, alors non. – imnotneo

+6

"Les changements nécessaires pour permettre l'utilisation d'autres bibliothèques seraient plus de travail." -- J'en doute. Au moins pas à long terme. De manière générale, Perl n'utilise pas de modules du CPAN, mais seulement la moitié de la langue. Refuser même d'utiliser de simples modules Perl purs, puis demander à d'autres de trouver des solutions à des problèmes précédemment résolus semble ... inefficace. – tsee

Répondre

13

This contient un correctif pour Regexp :: Common démontrant une regex IPv6 complète, précise et testée. C'est une traduction directe de la grammaire IPv6. Regexp::IPv6 est également précis.

Plus important encore, il contient une suite de tests. L'exécuter avec votre regex montre que vous êtes encore loin. 10 sur 19 manqués. 1 sur 12 faux positifs. IPv6 contient beaucoup de raccourcis spéciaux, ce qui rend très facile de se tromper subtilement.

Le meilleur endroit pour lire ce qui se passe dans une adresse IPv6 est RFC 3986 section 3.2.2.

+0

Quelqu'un sait s'il existe une version Python de cela? – jcollie

+0

@jcollie Ces regex n'utilisent pas de fonctionnalités Perl amusantes. Ils devraient être une traduction par cœur de Python. – Schwern

5

Je ne suis pas un expert IPv6, mais s'il vous plaît faites-moi confiance quand je vous dis que correspondant (encore moins la validation) Les adresses IPv6 ne sont pas faciles avec une regex très simple telle que celle que vous suggérez. Il y a beaucoup de raccourcis et diverses conventions pour combiner l'adresse avec un port, pour ne citer qu'un exemple. Un tel raccourci est que vous pouvez écrire 0: 0: 0: 0: 0: 0: 0: 1 comme :: 1, mais il y a plus. Si vous lisez l'allemand, je vous suggère de regarder les diapositives de Steffen Ullrich's talk lors du 11ème atelier allemand Perl. Vous dites que vous ne pouvez pas utiliser une bibliothèque, mais si vous allez réinventer toute la complexité de la bibliothèque, alors vous pouvez tout simplement l'importer textuellement dans votre projet. Qu'est-ce que vous voulez dire que vous ne pouvez pas simplement utiliser une bibliothèque?

10

Que diriez-vous d'un module? Regexp::IPv6 vous donnera ce dont vous avez besoin.

1

Si vous avez besoin de vérifier perl si une chaîne est une adresse IPv6, vous pouvez essayer ceci:

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

Cela fonctionne la plupart du temps ...

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

Inconvénients: :: comme les cas ne sont pas traités correctement

0

est ici celui travaillé pour tous les exemples d'IPv6 I AVONS réussi à trouver:

/^\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*$/ 

assurez-vous que c'est la ligne avant d'utiliser. il a été trouvé ici:

https://community.helpsystems.com/forums/intermapper/miscellaneous-topics/5acc4fcf-fa83-e511-80cf-0050568460e4

vérifié sur tous les exemples de la page question, la page de la communauté et le site wikipedia d'ici:

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

l'outil de vérification utilisées celui d'ici:

https://regex101.com/

Questions connexes