IPv6地址的正则表达式

4
我有一个用于IPv6地址的正则表达式,如下所示。
IPV4ADDRESS      [ \t]*(([[:digit:]]{1,3}"."){3}([[:digit:]]{1,3}))[ \t]*
x4               ([[:xdigit:]]{1,4})
xseq             ({x4}(:{x4}){0,7})
xpart            ({xseq}|({xseq}::({xseq}?))|::{xseq})
IPV6ADDRESS      [ \t]*({xpart}(":"{IPV4ADDRESS})?)[ \t]*

它可以正确地处理包括IPv6地址在内的所有格式

1) non-compressed IPv6 addresses
2) compressed IPv6 addresses
3) IPv6 addresses in legacy formats.(supporting IPv4)

IPv6地址的传统格式的优秀示例:

2001:1234::3210:5.6.7.8

     OR
2001:1234:1234:5432:4578:5678:5.6.7.8

As you can see above there are 10 groups separated by either `":" or ".".`

与普通IPv6地址中的8个组相反,这是因为由“.”分隔的最后4个组应压缩到IPv6地址的最不重要的32位中。因此,我们需要10个组来满足128位。

但是,如果我使用以下地址格式

   2001:1234:4563:3210:5.6.7.8

这里每个由“:”分隔的组表示16位。由“.”分隔的最后四个组表示8位。总比特数为64 + 32 = 96位。缺失32位。

正则表达式将其接受为有效的IPv6地址格式。我无法弄清楚如何修复正则表达式以丢弃这些值。非常感谢任何帮助。


1
你能解释一下提供的负面例子有什么问题吗? - Sina Iravanian
以上示例已经解释。每组由“:”分隔表示16位。由“.”分隔的最后四组表示8位。总位数为64 + 32 = 96位。缺失32位。 - liv2hak
1
它还接受像::0:999.999.999.999这样的无意义输入。 - nneonneo
我已经编写了代码来检查IPv4部分是否小于255。 - liv2hak
1个回答

5
以下是IPv6地址的语法,根据RFC 3986RFC 5954的规定而确定:
 IPv6address   =                             6( h16 ":" ) ls32
                /                       "::" 5( h16 ":" ) ls32
                / [               h16 ] "::" 4( h16 ":" ) ls32
                / [ *1( h16 ":" ) h16 ] "::" 3( h16 ":" ) ls32
                / [ *2( h16 ":" ) h16 ] "::" 2( h16 ":" ) ls32
                / [ *3( h16 ":" ) h16 ] "::"    h16 ":"   ls32
                / [ *4( h16 ":" ) h16 ] "::"              ls32
                / [ *5( h16 ":" ) h16 ] "::"              h16
                / [ *6( h16 ":" ) h16 ] "::"

 h16           = 1*4HEXDIG
 ls32          = ( h16 ":" h16 ) / IPv4address
 IPv4address   = dec-octet "." dec-octet "." dec-octet "." dec-octet
 dec-octet     = DIGIT                 ; 0-9
                / %x31-39 DIGIT         ; 10-99
                / "1" 2DIGIT            ; 100-199
                / "2" %x30-34 DIGIT     ; 200-249
                / "25" %x30-35          ; 250-255

使用这种方法,我们可以建立一个符合标准的用于IPv6地址的正则表达式。

dec_octet      ([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])
ipv4address    ({dec_octet}"."){3}{dec_octet}
h16            ([[:xdigit:]]{1,4})
ls32           ({h16}:{h16}|{ipv4address})
ipv6address    (({h16}:){6}{ls32}|::({h16}:){5}{ls32}|({h16})?::({h16}:){4}{ls32}|(({h16}:){0,1}{h16})?::({h16}:){3}{ls32}|(({h16}:){0,2}{h16})?::({h16}:){2}{ls32}|(({h16}:){0,3}{h16})?::{h16}:{ls32}|(({h16}:){0,4}{h16})?::{ls32}|(({h16}:){0,5}{h16})?::{h16}|(({h16}:){0,6}{h16})?::)

免责声明:未经测试。

此外,您还可以查看我的文章:正则表达式URI验证,其中包括IPv6和RFC-3986中指定的所有其他URI组件的正则表达式。 - ridgerunner

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接