如何使用Perl正则表达式匹配IPv6地址?

6

我需要匹配一个IPv6地址,该地址可能有掩码,也可能没有。不幸的是,我不能只使用库来解析字符串。

在这种情况下,掩码位很容易处理:

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

最困难的部分是IPv6地址的不同格式。它需要匹配::beef,beef ::,beef :: beef等。

更新:我快要完成了...

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

在这种情况下,我只能使用Perl的正则表达式。


2
我正在使用的语言是perl。允许使用其他库需要更多的工作。定义家庭作业?我在家里工作。这是我正在进行的项目之一 - 如果你是指教育目的,那么不是。 - imnotneo
6
“要允许使用其他库需要进行更多的工作。”--我表示怀疑。至少从长远来看不是这样。一般来说,Perl如果不使用来自CPAN的模块,只能发挥语言能力的一半。拒绝甚至使用简单的纯Perl模块,然后向他人寻求先前已经解决的问题的解决方案似乎是低效的。 - tsee
3
有什么变化吗?要么使用SomeModule,要么去CPAN下载模块并复制粘贴。 - innaM
5
确实如此,只是有些方法比其他方法好得多。 - innaM
5
理想情况下,这些方法不应该包括要求他人重新做已经完成的工作。如果你想找到另一种方法来完成任务,可以自由发挥,但现在你要求我们也参与其中。 - Ether
显示剩余4条评论
9个回答

13

这个包含了一个针对Regexp::Common的补丁,展示了一个完整、准确、经过测试的IPv6正则表达式。它是IPv6语法的直接转换。Regexp::IPv6也是准确的。

更重要的是,它包含了一个测试套件。使用你的正则表达式运行它会显示你还有很长的路要走。19个中有10个未通过测试,12个中有1个误报。IPv6包含许多特殊的缩写,使得它非常容易出现微妙的错误。

了解IPv6地址的构成方式最好的地方是RFC 3986的第3.2.2节。


有人知道这个的 Python 版本吗? - jcollie
@jcollie 这些正则表达式没有使用任何有趣的 Perl 特性。它们应该可以直接翻译成 Python。 - Schwern

10

你说不能只是用一个库吗?那模块呢?Regexp::IPv6 可以提供所需的功能。


5
我不是IPv6专家,但请相信我,使用像您提供的非常简单的正则表达式来匹配(更不用说验证)IPv6地址并不容易。有许多简写和各种约定来将地址与端口组合在一起,仅举一个例子。这样的一个简写是你可以把0:0:0:0:0:0:0:1写成::1,但还有更多。如果你懂德语,我建议你看看第11届德国Perl研讨会上Steffen Ullrich的演讲的幻灯片。
你说你不能使用库,但如果你打算重新发明整个库的复杂性,那么你可以直接将它完整地导入到你的项目中。

2

这基本上是有效的...

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

缺点::: 类似的情况未被正确处理。

2

尝试:

/^(((?=(?>.*?(::))(?!.+\3)))\3?|([\dA-F]{1,4}(\3|:(?!$)|$)|\2))(?4){5}((?4){2}|((2[0-4]|1\d|[1-9])?\d|25[0-5])(\.(?7)){3})\z/ai

From: http://home.deds.nl/~aeron/regex/


1
如果您需要在Perl中检查一个字符串是否为IPv6地址,可以尝试以下代码:
if (/(([\da-f]{0,4}:{0,2}){1,8})/i) { print("$1") };

1

这无法匹配2001:db8:85a3:0:0:8a2e:370:7334、2001:db8:85a3::8a2e:370:7334、2001:0db8:0000:0000:0000::1428:57ab、::ffff:c000:280以及其他很多。 - Schwern

1

这是我找到的所有IPv6示例中都适用的一个:

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

在使用之前,请确保它是上一行。

可以在这里找到它:

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

已在问题页面、社区页面和维基百科页面上的所有示例中进行验证:

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

这里使用的验证工具是从这里获取的:

https://regex101.com/


在我的日志文件中运行良好。甚至给了我以下几行:命令通道监听::1#xxx // DNS套接字创建于[::],FD 3 // 接受本地=[::]:xxxx远程=[::] FD 4标志=33的NAT拦截HTTP套接字连接 // 接受本地=[::]:xxxx远程=[::] FD 5标志=8的HTTP套接字连接 // 监听::1 // 监听xxxx::xxxx:xxxx:xxxx:xxxx%eth0 // 监听xxxx::xxxx:xxxx:xxxx:xxxx%eth1 // 为用户admin@::ffff:xxx.xxx.xxx.xxx打开会话 - MacMartin

0

这是一个全面的IPv6正则表达式,它测试所有有效的IPv6文本表示形式(扩展、压缩、扩展混合、压缩混合),并附带可选前缀长度。它还将各个部分捕获到捕获组中。您可以通过在捕获组的开头加上?:来跳过捕获组。

这是我在我的IPvX IP计算器中创建和使用的正则表达式,用于IPv4和IPv6。

^# Anchor
  (# BEGIN Compressed-mixed                                         *** Group 1 ***
    (# BEGIN Hexadecimal Notation                                   *** Group 2 ***
       (?:
         (?:[0-9A-F]{1,4}:){5}[0-9A-F]{1,4}            # No ::
       | (?:[0-9A-F]{1,4}:){4}:[0-9A-F]{1,4}           # 4::1
       | (?:[0-9A-F]{1,4}:){3}(?::[0-9A-F]{1,4}){1,2}  # 3::2
       | (?:[0-9A-F]{1,4}:){2}(?::[0-9A-F]{1,4}){1,3}  # 2::3
       | [0-9A-F]{1,4}:(?::[0-9A-F]{1,4}){1,4}         # 1::4
       | (?:[0-9A-F]{1,4}:){1,5}                       # :: End
       | :(?::[0-9A-F]{1,4}){1,5}                      # :: Start
       | :                                             # :: Only
       ):
    )# END Hexadecimal Notation
    (# BEGIN Dotted-decimal Notation                                *** Group 3 ***
       (25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\. # 0 to 255.  *** Group 4 ***
       (25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\. # 0 to 255.  *** Group 5 ***
       (25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\. # 0 to 255.  *** Group 6 ***
       (25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])   # 0 to 255   *** Group 7 ***
    )# END Dotted-decimal Notation
  )# END Compressed-mixed
  |
  (# BEGIN Compressed                                               *** Group 8 ***
     (?:# BEGIN Hexadecimal Notation
       (?:[0-9A-F]{1,4}:){7}[0-9A-F]{1,4}              # No ::
     | (?:[0-9A-F]{1,4}:){6}:[0-9A-F]{1,4}             # 6::1
     | (?:[0-9A-F]{1,4}:){5}(?::[0-9A-F]{1,4}){1,2}    # 5::2
     | (?:[0-9A-F]{1,4}:){4}(?::[0-9A-F]{1,4}){1,3}    # 4::3
     | (?:[0-9A-F]{1,4}:){3}(?::[0-9A-F]{1,4}){1,4}    # 3::4
     | (?:[0-9A-F]{1,4}:){2}(?::[0-9A-F]{1,4}){1,5}    # 2::5
     | [0-9A-F]{1,4}:(?::[0-9A-F]{1,4}){1,6}           # 1::6
     | (?:[0-9A-F]{1,4}:){1,7}:                        # :: End
     | :(?::[0-9A-F]{1,4}){1,7}                        # :: Start
     | ::                                              # :: Only
     )  # END Hexadecimal Notation
  )# END Compressed
  (?:# BEGIN Optional Length
       /(12[0-8]|1[0-1][0-9]|[1-9]?[0-9])              # /0 to /128 *** Group 9 ***
  )? # END Optional Length
$# Anchor

IPv4正则表达式奖励:

^# Anchor
  (?:# BEGIN Dotted-decimal Notation
       (25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\. # 0 to 255.  *** Group 1 ***
       (25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\. # 0 to 255.  *** Group 2 ***
       (25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\. # 0 to 255.  *** Group 3 ***
       (25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])   # 0 to 255   *** Group 4 ***
  )  # END Dotted-decimal Notation
  (?:# BEGIN Optional Length
       /(3[0-2]|[1-2]?[0-9])                           # /0 to /32  *** Group 5 ***
  )? # END Optional Length
$# Anchor

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