【问题标题】:How can I match IPv6 addresses with a Perl regex?如何将 IPv6 地址与 Perl 正则表达式匹配?
【发布时间】:2010-12-20 15:18:10
【问题描述】:

所以我需要匹配一个可能有也可能没有掩码的 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 的正则表达式。

【问题讨论】:

  • 我使用的语言是 perl。允许使用其他库所需的更改将是更多的工作。定义作业?我在家,我在工作。这是我正在从事的项目之一 - 如果您的意思是出于教育目的,那么没有。
  • “允许使用其他库所需的更改将是更多工作。” - 我对此表示怀疑。至少从长远来看不会。一般来说,不使用 CPAN 模块的 Perl 只是语言的一半。甚至拒绝使用简单的纯 Perl 模块,然后向其他人寻求以前解决的问题的解决方案似乎......效率低下。
  • 有什么变化?要么是use SomeModule,要么你去CPAN,下载模块并复制粘贴。
  • 确实如此。只是有些方法比其他方法好很多。
  • 理想情况下,这些方式不应包括要求他人重做已经完成的工作。如果您想找到另一种方法,那就发疯,但您现在也要求我们参与其中。

标签: regex perl ipv6


【解决方案1】:

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

更重要的是,它包含一个测试套件。用你的正则表达式运行它表明你还有很长的路要走。 19 人中有 10 人错过了。 12 个误报中的 1 个。 IPv6 包含许多特殊的速记,因此很容易出错。

了解 IPv6 地址中的内容的最佳位置是RFC 3986 第 3.2.2 节。

【讨论】:

  • 有人知道这是否有 Python 版本吗?
  • @jcollie 那些正则表达式没有使用任何有趣的 Perl 特性。它们应该是对 Python 的死记硬背。
【解决方案2】:

你的意思是你不能只使用图书馆?一个模块怎么样? Regexp::IPv6 会给你你所需要的。

【讨论】:

    【解决方案3】:

    我不是 IPv6 专家,但是当我告诉您使用非常简单的正则表达式(例如您建议的那个)来匹配(更不用说验证)IPv6 地址并不容易时,请相信我。将地址与端口组合起来有许多简写和各种约定,仅举一个例子。一种这样的速记是您可以将 0:0:0:0:0:0:0:1 写为 ::1,但还有更多。如果您阅读德语,我建议您在第 11 届德语 Perl 研讨会上查看 Steffen Ullrich's talk 的幻灯片。

    您说您不能使用库,但如果您要重新发明库的整个复杂性,那么您也可以将其逐字导入您的项目中。

    【讨论】:

      【解决方案4】:

      这主要是可行的......

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

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

      【讨论】:

        【解决方案5】:

        试试这个:

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

        来自Regular Expression Library: IPv6 address

        您还应该阅读以下内容:A Regular Expression for IPv6 Addresses

        【讨论】:

        • 这无法匹配 2001:db8:85a3:0:0:8a2e:370:7334 2001:db8:85a3::8a2e:370:7334 2001:0db8:0000:0000:0000:: 1428:57ab ::ffff:c000:280 和更多。
        【解决方案6】:

        如果你需要在 perl 中检查一个字符串是否是一个 IPv6 地址,你可以试试这个:

        if (/(([\da-f]{0,4}:{0,2}){1,8})/i) { print("$1") };
        

        【讨论】:

          【解决方案7】:

          试试:

          /^(((?=(?>.*?(::))(?!.+\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
          

          来自: http://home.deds.nl/~aeron/regex/

          【讨论】:

            【解决方案8】:

            这是我设法找到的所有 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/

            【讨论】:

            • 在日志文件中为我工作。甚至给了我以下几行command channel listening on ::1#xxx // DNS Socket created at [::], FD 3 // Accepting NAT intercepted HTTP Socket connections at local=[::]:xxxx remote=[::] FD 4 flags=33 // Accepting HTTP Socket connections at local=[::]:xxxx remote=[::] FD 5 flags=8 // listening on ::1 // listening on xxxx::xxxx:xxxx:xxxx:xxxx%eth0 // listening on xxxx::xxxx:xxxx:xxxx:xxxx%eth1 // session opened for user admin@::ffff:xxx.xxx.xxx.xxx
            猜你喜欢
            • 2012-04-27
            • 1970-01-01
            • 1970-01-01
            • 2015-11-28
            • 2013-01-16
            • 2011-05-12
            • 1970-01-01
            • 2022-12-07
            • 1970-01-01
            相关资源
            最近更新 更多