2

我想要一个可以同时封装 ipv4 子网掩码和 ipv6 前缀长度(1-128)的正则表达式。我正在考虑扩展以下 ptype 以包括前缀长度以及 PTYPE name="IP_ADDR"

pattern="(((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))"
help="IP address AAA.BBB.CCC.DDD where each part is in the range 0-255"/>

新模式看起来像这样。

pattern="((((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)) | (12[0-8]| 1[01][0-9] | [01]?[0-9][0-9]?))"

上面的模式对吗?有人可以建议一种更好的方法来编写模式吗?

4

1 回答 1

0

您现在可能已经弄清楚了,但是您的正则表达式唯一真正的问题是您没有指定边界。因此,正如您在评论中所说,300 将导致匹配。这是因为它与 30 匹配。如果您添加了单词边界\b,那么您的匹配将起作用:

\b(12[0-8]|1[01][0-9]|([1-9][0-9]?))\b

只会匹配 1 到 128。这是有效的,因为它只允许匹配在匹配之前有单词边界的情况下成功。300 现在失败了,因为 30 后面是 0 而不是单词边界。

我将其简化为:

\b([1-9][0-9]?|[1][0-2][0-8])\b

在 ipv6 地址的情况下,格式为:

<address>/<subnet mask>

那么上面的正则表达式仍然可以工作,因为 / 不是一个单词字符(是一个边界)。但是,如果您特别想检查前面的内容,/那么您会这样做:

(?<=/)([1-9][0-9]?|[1][0-2][0-8])\b

(?<=/)是一个积极的回顾。它确保匹配前面有一个/. 请注意,它是一个零长度断言,这意味着它不计入匹配的一部分,因此您的匹配仍然只包含子网号。

于 2014-01-26T12:20:51.473 回答