Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I match IPv6 addresses with a Perl regex?

Tags:

regex

perl

ipv6

So I need to match an ipv6 address which may or may not have a mask. Unfortunately I can't just use a library to parse the string.

The mask bit is easy enough, in this case:

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

The hard part is the different formats of an ipv6 address. It needs to match ::beef, beef::, beef::beef, etc.

An update: I'm almost there..

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

I am, in this case restricted to using perl's regex.

like image 772
imnotneo Avatar asked Nov 26 '09 09:11

imnotneo


1 Answers

This contains a patch to Regexp::Common demonstrating a complete, accurate, tested IPv6 regex. Its a straight translation of the IPv6 grammar. Regexp::IPv6 is also accurate.

More importantly, it contains a test suite. Running it with your regex shows you're still a ways off. 10 out of 19 missed. 1 out of 12 false positives. IPv6 contains a lot of special shorthands making it very easy to get subtly wrong.

Best place to read up on what goes into an IPv6 address is RFC 3986 section 3.2.2.

like image 111
Schwern Avatar answered Nov 15 '22 00:11

Schwern