[英]The RegEx pattern for matching the entire specific sets of IP address class?
[英]LEX Pattern for matching compressed textual representation of an IP version 6 address
我知道有很多关于堆栈溢出和其他正则表达式的帖子,包括 IPV6 地址的 LEX 模式。 它们似乎都不是真正完整的,并且确实有些要求不需要解析所有可能的地址格式。
我正在寻找 IP 版本 6 地址的 LEX 模式,仅适用于以压缩文本形式表示的地址。 这种形式在RFC 5952 (以及可能的其他相关 RFC)的第 2.2 节中进行了描述,并且代表了所有可能的 IPv6 地址格式的一个相对较小的子集。
如果有人有一个经过良好测试或知道的,请转发。
RFC 5952 §2.2没有正式描述压缩的 IPv6 地址形式。 RFC 5952 的目标是产生一种“规范的文本表示形式”; 也就是说,一组文本编码与 IPv6 地址集具有一对一的关系。 第 2.2 节列举了导致编码选项的压缩形式的几个方面; 规范表示需要消除所有选项。
压缩语法实际上在RFC 4291 §2.2的第 2 节中描述。 该语法很容易描述为正则表达式,尽管它有点烦人; 在包含两个正则表达式的交集的语法中会更容易(例如,Ragel 提供了该运算符),但在这种情况下,简单的可能性枚举就足够了。
如果您真的想将匹配限制为RFC 5952 §4.2中列出的规范表示,那么您有一个稍微艰巨的任务,因为要求 0 的压缩运行必须是未压缩地址中 0 的最长运行,或者如果有多个相同长度的最长运行,则第一次运行。
这可以通过对允许的 forms 进行更长的枚举来实现,其中压缩运行满足“第一最长”约束。 但我真的不确定创建那个怪物有什么价值,因为 RFC 5952 非常清楚其意图是限制由符合要求的应用程序生成的表示集(强调添加):
…[A]所有实现必须接受并能够处理任何合法的 RFC4291格式。
由于正则表达式主要用于识别和解析输入,go 似乎没有必要编写和验证可能的规范模式列表。
符合RFC 4291 §2.2第 1 条的 IPv6 地址可以很容易地用 lex 语法描述:
piece [[:xdigit:]]{1,4}
%%
{piece}(:{piece}){7} { /* an uncompressed IPv6 address */ }
顺便说一句,尽管出于上述相同的原因似乎没有必要,但将{piece}
限制为规范的 16 位表示非常简单(仅小写,没有前导零):
piece 0|[1-9a-f][0-9a-f]{0,3}
复杂性来自第 2 节中的要求,即仅压缩一次运行的 0。 编写一个只允许省略一个数字的正则表达式很容易:
(({piece}:)*{piece})?::({piece}(:{piece})*)?
但是该公式不再将片段数限制为 8。编写允许省略片段的正则表达式也相当容易,从而限制了字段的数量:
{piece}(:{piece}?){1,6}:{piece}|:(:{piece}){1,7}|({piece}:){1,7}:|::
需要的是这两种模式的交集,加上未压缩地址的模式。 但是,如前所述,没有办法在 (f)lex 中编写交集。 所以我们最终列举了各种可能性。 一个简单的枚举是初始未压缩片段的数量:
(?x: /* Flex's extended syntax allows whitespace and continuation lines */
{piece}(:{piece}){7}
| {piece} ::{piece}(:{piece}){0,5}
| {piece}:{piece} ::{piece}(:{piece}){0,4}
| {piece}(:{piece}){2}::{piece}(:{piece}){0,3}
| {piece}(:{piece}){3}::{piece}(:{piece}){0,2}
| {piece}(:{piece}){4}::{piece}(:{piece})?
| {piece}(:{piece}){5}::{piece}
| {piece}(:{piece}){0,6}::
| ::{piece}(:{piece}){0,6}
| ::
)
这仍然不包括在 IPv6 中嵌入 IPv4 地址的各种 forms,但如果需要,应该清楚如何添加这些地址。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.