【问题标题】:Regex for IPaddress/prefixIP地址/前缀的正则表达式
【发布时间】:2011-10-24 04:31:02
【问题描述】:

我有一个用于 IP 地址验证的正则表达式,但我需要一个用于前缀验证的正则表达式,其中预期的形式是“IP 地址/前缀”。

条件是:

  1. 前缀值不能大于128

  2. 前缀值应该能被4整除。

谁能帮我创建一个用于前缀验证的正则表达式?

【问题讨论】:

  • 能否请您发布一个示例 ipaddress 以及前缀值是什么样的?
  • 所有数字都能被 4 整除。你的意思是“能整除”吗?
  • Marc B:从数论来看,“可除”一词的意思总是“能整除”。
  • regexp 是这个工作的错误工具。您真的需要正则表达式解决方案,还是只是猜测自己需要?

标签: java regex ip-address


【解决方案1】:

除了使用正则表达式,您还可以这样做:

int prefix = Integer.parseInt(ipAddress.split(".")[0]);
if ( (prefix <= 128) && (prefix % 4 == 0)) {
    //success
}
else {
    //failure
}

【讨论】:

  • 这比一些看不懂的正则表达式要好很多。
【解决方案2】:

AFAIK 您无法使用正则表达式进行计算(例如 number % 4 == 0 ?)。因此,您必须使用一种模式来获取所有可能的字符串组合。

试试那个:\b[048]\b|\b[13579][26]\b|\b[2468][048]\b|\b1[02][048]\b|\b11[26]\b

  • \b[048]\b 匹配 0、4 和 8
  • \b[13579][26]\b 匹配 12、16、32、26 等。
  • \b[2468][048]\b 匹配 20、24、28、40、44、48 等。
  • \b1[02][048]\b 匹配 100、104、108、120、124、128
  • \b11[26]\b 匹配 112 和 116

注意 \b 定义整个单词(在您的情况下为前缀/后缀)必须与模式匹配。例如,如果没有它,136 可能会匹配 [13579][26]

编辑:允许前导零将模式更改为:\b0{0,2}[048]\b|\b0?[13579][26]\b|\b0?[2468][048]\b|\b1[02][048]\b|\b11[26]\b(注意0{0,2} 也可以写为0?0?)。

编辑2:如果您拆分IP地址并且只有一个包含前缀/后缀的字符串,您可能会摆脱\b。如果你然后打电话给matches(...),你应该没问题\b

matches(...) 调用的模式(无 \b,允许前导零):
0{0,2}[048]|0?[13579][26]|0?[2468][048]|1[02][048]|11[26]

【讨论】:

  • 不,136 不会匹配 [13579][26]
  • @aioobe 这取决于它是如何被调用的。 136 不会作为一个整体匹配,但其中的 36 部分可能会匹配。
  • 对,只要你坚持String.machesMatcher.matches 并避免Matcher.find 等,你应该没问题。或者你可以用^...$替换所有\b我想。
  • 这个答案的编辑和 cmets 正是你不想使用正则表达式来解决这个问题的原因。正确与否很难理解。
【解决方案3】:

如果要验证 IP 地址子网前缀号,可以通过包含 4 到 128 的倍数来通过蛮力构建正则表达式:/0|4|8|12|16|20|24|28|32|...|120|124|128/

如果 4 的倍数以偶数+{0,4,8} 或奇数+{2,6} 结尾,您可以稍微简化一下。

除了这种蛮力方法之外,没有其他方法可以干净而紧凑地实现您想要的 - 正则表达式适用于单个字符,而不是数字的语义解释(因此没有比较,没有算术)。

【讨论】:

  • 这比尝试制作花哨模式的解决方案(即:Thomas 的解决方案)要好得多。它可能会很长,但它会执行得很快,并且匹配的内容会立即一目了然。
  • 当我谈到“以两位数结束[ing]”时,我确实提到了 Thomas 的解决方案,呵呵。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-06-20
  • 2017-03-15
  • 2015-11-22
  • 2013-02-21
相关资源
最近更新 更多