用于验证 IPv4 和 IPv6 地址的 Javascript 正则表达式,没有主机名

Posted

技术标签:

【中文标题】用于验证 IPv4 和 IPv6 地址的 Javascript 正则表达式,没有主机名【英文标题】:Javascript regex to validate IPv4 and IPv6 address, no hostnames 【发布时间】:2014-06-22 10:14:28 【问题描述】:

请推荐一个可以验证的 JS 正则表达式:

IPv4 地址 IPv6 地址

这个正则表达式应该只验证地址而不验证主机名。

【问题讨论】:

【参考方案1】:

我有完全相同的必要性,所以我调整了 Daniel's great answer 的正则表达式(这是我能找到的最准确的)来不验证主机名。 这里是:

var expression = /((^\s*((([0-9]|[1-9][0-9]|1[0-9]2|2[0-4][0-9]|25[0-5])\.)3([0-9]|[1-9][0-9]|1[0-9]2|2[0-4][0-9]|25[0-5]))\s*$)|(^\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*$))/;

if (expression.test(valueToTest))

    // good IP

else

    // bad IP

我 fork Daniel's original JSFiddle 使用这个修改后的版本,因为我喜欢他提供的大量示例列表。您可以找到modified JSFiddle here,它应该符合您的需求。

希望这对我有所帮助! :)

【讨论】:

请原谅我再次提出这个老问题,但以上都没有对我有用,因为 Pedro Lobito 的回答 validates "house" as a valid IP,而且我正在寻找 IPv4 和 IPv6 的单一表达式。 测试中的一些错误:“::2:3:4:5:6:7:8”不应是有效的 IPv6。 “::”不能用于一个“0”段。它应该是“0:2:3:4:5:6:7:8”,因为每个 ipv6 限制为 8 个四重奏,而不是 9 个。对于“::0:0:0:0:0:0”也是如此:0", "::0:a:b:c:d:e:f", ":::2222:3333:4444:5555:6666:7777:8888", "::2222:3333:4444: 5555:6666:7777:8888" 测试中出现更多错误:"::2222:3333:4444:5555:6666:123.123.123.123" 无效,因为末尾的 ipv4 代表 4 个字节,所以是 2 个四重奏,总共标记9个四重奏而不是8个,所以它是无效的。 “1111:2222:3333:4444:5555:6666:000.000.000.000”是有效的,如果你认为 ipv4 “000.000.000.000”是有效的,同样对于“1111:2222:3333:4444:5555:6666:00.00”。 00.00"【参考方案2】:

我能找到的最新且正确的正则表达式位于 npm 包中:ip-regex。

在对 vanillas javascript 进行一些修改并进行相应测试后,您可以像这样使用它:

IPv4 正则表达式:

let ipv4_regex = /^(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d))3$/gm;   
      
console.log(ipv4_regex.test('1.1.1.1'));
console.log(ipv4_regex.test('.100.100.100.100'));
console.log(ipv4_regex.test('256.100.100.100.100'));

IPv6 正则表达式:

let ipv6_regex = /^(?:(?:[a-fA-F\d]1,4:)7(?:[a-fA-F\d]1,4|:)|(?:[a-fA-F\d]1,4:)6(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d))3|:[a-fA-F\d]1,4|:)|(?:[a-fA-F\d]1,4:)5(?::(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d))3|(?::[a-fA-F\d]1,4)1,2|:)|(?:[a-fA-F\d]1,4:)4(?:(?::[a-fA-F\d]1,4)0,1:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d))3|(?::[a-fA-F\d]1,4)1,3|:)|(?:[a-fA-F\d]1,4:)3(?:(?::[a-fA-F\d]1,4)0,2:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d))3|(?::[a-fA-F\d]1,4)1,4|:)|(?:[a-fA-F\d]1,4:)2(?:(?::[a-fA-F\d]1,4)0,3:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d))3|(?::[a-fA-F\d]1,4)1,5|:)|(?:[a-fA-F\d]1,4:)1(?:(?::[a-fA-F\d]1,4)0,4:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d))3|(?::[a-fA-F\d]1,4)1,6|:)|(?::(?:(?::[a-fA-F\d]1,4)0,5:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d))3|(?::[a-fA-F\d]1,4)1,7|:)))(?:%[0-9a-zA-Z]1,)?$/gm;     
          
console.log(ipv6_regex.test('2606:4700:4700::64'));
console.log(ipv6_regex.test('::1111:2222:3333:4444:5555:6666::'));
console.log(ipv6_regex.test('1:2:3::4:5::7:8'));

IPv4 + IPv6 组合正则表达式

let ipv46_regex = /(?:^(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d))3$)|(?:^(?:(?:[a-fA-F\d]1,4:)7(?:[a-fA-F\d]1,4|:)|(?:[a-fA-F\d]1,4:)6(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d))3|:[a-fA-F\d]1,4|:)|(?:[a-fA-F\d]1,4:)5(?::(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d))3|(?::[a-fA-F\d]1,4)1,2|:)|(?:[a-fA-F\d]1,4:)4(?:(?::[a-fA-F\d]1,4)0,1:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d))3|(?::[a-fA-F\d]1,4)1,3|:)|(?:[a-fA-F\d]1,4:)3(?:(?::[a-fA-F\d]1,4)0,2:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d))3|(?::[a-fA-F\d]1,4)1,4|:)|(?:[a-fA-F\d]1,4:)2(?:(?::[a-fA-F\d]1,4)0,3:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d))3|(?::[a-fA-F\d]1,4)1,5|:)|(?:[a-fA-F\d]1,4:)1(?:(?::[a-fA-F\d]1,4)0,4:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d))3|(?::[a-fA-F\d]1,4)1,6|:)|(?::(?:(?::[a-fA-F\d]1,4)0,5:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d))3|(?::[a-fA-F\d]1,4)1,7|:)))(?:%[0-9a-zA-Z]1,)?$)/gm;      
      
console.log(ipv46_regex.test('1.1.1.1'));
console.log(ipv46_regex.test('.100.100.100.100'));
console.log(ipv46_regex.test('256.100.100.100.100'));
console.log(ipv46_regex.test('2606:4700:4700::64'));
console.log(ipv46_regex.test('::1111:2222:3333:4444:5555:6666::'));
console.log(ipv46_regex.test('1:2:3::4:5::7:8'));

享受吧。

【讨论】:

【参考方案3】:

在我认为找不到更好的解决方案同时适用于 IPv4 和 IPv6 时,我编译了这些正则表达式公式。根据我自己的要求,它确实包括捕获组,但它应该不会影响它的工作与否。

IPv4 正则表达式:

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

IPv6 正则表达式:

^((?:[0-9A-Fa-f]1,4))((?::[0-9A-Fa-f]1,4))*::((?:[0-9A-Fa-f]1,4))((?::[0-9A-Fa-f]1,4))*|((?:[0-9A-Fa-f]1,4))((?::[0-9A-Fa-f]1,4))7$

实现示例:

IPv4: if ( /^([01]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])\\.([01]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])\\.([01]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])\\.([01]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])$/g.test(ipv4)) 
IPv6: if ( /^((?:[0-9A-Fa-f]1,4))((?::[0-9A-Fa-f]1,4))*::((?:[0-9A-Fa-f]1,4))((?::[0-9A-Fa-f]1,4))*|((?:[0-9A-Fa-f]1,4))((?::[0-9A-Fa-f]1,4))7$/g.test(ipv6)) 

我对 Regex 有点陌生,因此我们将不胜感激对我的尝试提供反馈。

【讨论】:

请不要以为您的 ipv6 正则表达式无效。诸如此类的值是行不通的。 (请忽略子网符号)en.wikipedia.org/wiki/IPv6_address#Default_address_selection 这意味着地址 1:: 和地址 ::1 在您的示例中不起作用 也不是这样的字符串对于您的 ipv6 regedit 也是有效的 1:4:1:2:2:2::2:2:2:1:1:21:1跨度> 当我第一次开发这些公式时,我对有效的 IPv6 地址知之甚少。事实上,我对他们还是有点模糊。就像我说的,我不是正则表达式的专家,但是当我在其他地方找不到答案时,我能够制定这些并且它们满足了我的要求。 IPv4 Regex根本不起作用,IPv6 Regex有问题。 7 年后,我认为最好正确更新这个答案......因为这篇文章的索引非常好。

以上是关于用于验证 IPv4 和 IPv6 地址的 Javascript 正则表达式,没有主机名的主要内容,如果未能解决你的问题,请参考以下文章

ipv4 ipv6哪个上网速度快

Code-Validator:验证网址(可以匹配IPv4地址但没对IPv4地址进行格式验证;IPv6暂时没做匹配)

在 Java 中验证 IPv4 地址

如何确定字符串是 C# 中的有效 IPv4 还是 IPv6 地址?

ipv6的地址类型中用于分配给用户主机的是哪种类型?求大神帮助

将 IPV4 转换为 IPV6 php