【问题标题】:regular expression for IPv6 addressesIPv6 地址的正则表达式
【发布时间】:2013-01-16 07:37:14
【问题描述】:

我有一个 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 地址格式。我无法弄清楚如何修复正则表达式以丢弃此类值。非常感谢任何帮助。

【问题讨论】:

  • 你能解释一下所提供的反面例子有什么问题吗?
  • 上面的例子已经解释过了。每组用“:”隔开代表16位。最后四组用“.”隔开表示 8 位。总位数为 64 + 32 = 96 位。缺少 32 位。
  • 嗯,它也接受 ::0:999.999.999.999 之类的废话。
  • 我有代码检查 ipv4 部分是否为

标签: c regex networking ipv6 flex-lexer


【解决方案1】:

这是RFC 3986 中给出并随后在RFC 5954 中确认的 IPv6 地址语法:

 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})?::)

免责声明:未经测试。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-13
  • 1970-01-01
  • 1970-01-01
  • 2015-11-28
  • 2010-12-20
  • 2014-01-27
相关资源
最近更新 更多