谁有一个正则表达式,可以匹配任何合法的DNS主机名或IP地址?

编写一个95%的工作时间很容易,但我希望得到一个经过良好测试的东西,完全匹配DNS主机名的最新RFC规范。


当前回答

我认为这是最好的Ip验证规则。请检查一次!!

^(([01]?[0-9]?[0-9]|2([0-4][0-9]|5[0-5]))\.){3}([01]?[0-9]?[0-9]|2([0-4][0-9]|5[0-5]))$

其他回答

新的网络框架为结构IPv4Address和结构IPv6Address提供了可失败的初始化器,可以很容易地处理IP地址部分。在IPv6中使用regex实现这一点很困难,因为所有的缩短规则。

不幸的是,对于主机名,我没有一个优雅的答案。

注意,网络框架是最近的,所以它可能会强迫你编译最新的操作系统版本。

import Network
let tests = ["192.168.4.4","fkjhwojfw","192.168.4.4.4","2620:3","2620::33"]

for test in tests {
    if let _ = IPv4Address(test) {
        debugPrint("\(test) is valid ipv4 address")
    } else if let _ = IPv6Address(test) {
        debugPrint("\(test) is valid ipv6 address")
    } else {
        debugPrint("\(test) is not a valid IP address")
    }
}

output:
"192.168.4.4 is valid ipv4 address"
"fkjhwojfw is not a valid IP address"
"192.168.4.4.4 is not a valid IP address"
"2620:3 is not a valid IP address"
"2620::33 is valid ipv6 address"

试试这个:

((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)

这对我来说是有效的。

我认为这是最好的Ip验证规则。请检查一次!!

^(([01]?[0-9]?[0-9]|2([0-4][0-9]|5[0-5]))\.){3}([01]?[0-9]?[0-9]|2([0-4][0-9]|5[0-5]))$

值得注意的是,大多数语言都有这样的库,它们通常内置在标准库中。这些库的更新频率可能比你四年前从Stack Overflow的答案中复制而忘记的代码要高得多。当然,他们通常也会把地址解析成一些可用的形式,而不仅仅是给你一堆组的匹配。

例如,在(POSIX) C中检测和解析IPv4:

#include <arpa/inet.h>
#include <stdio.h>

int main(int argc, char *argv[]) {
  for (int i=1; i!=argc; ++i) {
    struct in_addr addr = {0};
    printf("%s: ", argv[i]);
    if (inet_pton(AF_INET, argv[i], &addr) != 1)
      printf("invalid\n");
    else
      printf("%u\n", addr.s_addr);
  }
  return 0;
}

显然,如果您试图查找聊天消息中的所有有效地址,这样的函数将不起作用——但即使这样,使用一个简单但过于热心的正则表达式来查找潜在的匹配,然后使用库来解析它们可能会更容易。

例如,在Python中:

>>> import ipaddress
>>> import re
>>> msg = "My address is 192.168.0.42; 192.168.0.420 is not an address"
>>> for maybeip in re.findall(r'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}', msg):
...     try:
...         print(ipaddress.ip_address(maybeip))
...     except ValueError:
...         pass
>>> my_hostname = "testhostn.ame"
>>> print bool(re.match("^(([a-zA-Z]|[a-zA-Z][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z]|[A-Za-z][A-Za-z0-9\-]*[A-Za-z0-9])$", my_hostname))
True
>>> my_hostname = "testhostn....ame"
>>> print bool(re.match("^(([a-zA-Z]|[a-zA-Z][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z]|[A-Za-z][A-Za-z0-9\-]*[A-Za-z0-9])$", my_hostname))
False
>>> my_hostname = "testhostn.A.ame"
>>> print bool(re.match("^(([a-zA-Z]|[a-zA-Z][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z]|[A-Za-z][A-Za-z0-9\-]*[A-Za-z0-9])$", my_hostname))
True