I think all the corner cases in IPv6 addresses are likely to make you crazy if you try to do the whole problem in an RE. You could try the is_ipv6 function here:
my $quad = "[0-9a-fA-F]{0,4}"; my $ipv6addr = "(?:$quad:){2,7}$quad"; sub is_ipv6 { local $_ = $_[0]; return 0 unless m{^$ipv6addr(?:/(\d+))?$}; my $mask = defined($1) ? $1 : 128; # in 5.10: my $mask = $1 // 128; return 0 if /:::/ or /::.*::/ or not /::/ and 7 != tr/:/:/; return ( 0 <= $mask and $mask <= 128 ); }
But you might be better off to just go ahead and try to convert the address with NetAddr::IP -> new6, and see if the result is true. A quick and dirty test comparing the two approaches...
use warnings; use strict; use NetAddr::IP; my $quad = "[0-9a-fA-F]{0,4}"; my $ipv6addr = "(?:$quad:){2,7}$quad"; sub is_ipv6 { local $_ = $_[0]; return 0 unless m{^$ipv6addr(?:/(\d+))?$}; my $mask = defined($1) ? $1 : 128; # in 5.10: my $mask = $1 // 128; return 0 if /:::/ or /::.*::/ or not /::/ and 7 != tr/:/:/; return ( 0 <= $mask and $mask <= 128 ); } while (<DATA>) { chomp; printf "%-25s ", $_; my $addr = NetAddr::IP -> new6 ($_); $addr ||= ""; printf "%-25s ", $addr; print is_ipv6($_) ? "yes\n" : "no\n"; } __DATA__ :: ::/0 ::1/128 1::/64 : :/96 2001:1::/64 2001:0:6:4003::/64 2001::12/128 2001::15/0 2001::15/-1 2001::15/129 20012::15/96 2001:1:::2/96 2001::1::2/96 2001::1:2::3/96 2001:2:3:4:5:6:7/48 2001:2:3:4::6:7/48 2001:2:3:4:5:6:7:8/64 2001:2:3:4:5:6:7:8:9/96 2001:2:3:4::6:7:8:9/96
prints the following:
:: 0:0:0:0:0:0:0:0/128 yes ::/0 0:0:0:0:0:0:0:0/0 yes ::1/128 0:0:0:0:0:0:0:1/128 yes 1::/64 1:0:0:0:0:0:0:0/64 yes : no :/96 no 2001:1::/64 2001:1:0:0:0:0:0:0/64 yes 2001:0:6:4003::/64 2001:0:6:4003:0:0:0:0/64 yes 2001::12/128 2001:0:0:0:0:0:0:12/128 yes 2001::15/0 2001:0:0:0:0:0:0:15/0 yes 2001::15/-1 no 2001::15/129 no 20012::15/96 no 2001:1:::2/96 no 2001::1::2/96 no 2001::1:2::3/96 no 2001:2:3:4:5:6:7/48 no 2001:2:3:4::6:7/48 2001:2:3:4:0:0:6:7/48 yes 2001:2:3:4:5:6:7:8/64 2001:2:3:4:5:6:7:8/64 yes 2001:2:3:4:5:6:7:8:9/96 no 2001:2:3:4::6:7:8:9/96 no

In reply to Re: Regex host portion of IPv6 address by quester
in thread Regex host portion of IPv6 address by ewhitt

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.