如何使用正则表达式正确验证 IP 地址,重点关注 IPv6 规范零段折叠和双堆栈地址?

问题描述 投票:0回答:1

为了各种目的,我一直在寻找正确且有效设计的正则表达式(RegEx、RegExp),但在这篇文章中,我重点关注 IPv4 和 IPv6 地址验证。

在此特定情况下,正则表达式的目标环境是 JavaScript(Web 浏览器、NodeJS)以及 HTML5 模式属性用法。

到目前为止,我在网上找到的正则表达式还没有很好地满足

correctness
和/或
efficiency
标准。我将在下面给出这些问题的一些示例和一组不完整的测试用例,以描述遇到的问题。

目标 - 正则表达式

  • 应尽可能减少回溯。
  • 如果可能,应根据预期频率对模式的类别和部分进行排序。
  • 如果可能,应遵循任何其他性能和简洁性注意事项。

目标 - IPv6:

  • 当且仅当地址完全展开(完全展开)时才允许使用前导零。
  • 单段零序列不应折叠。
  • 如果一个零序列被折叠,则应折叠相邻零段的完整序列(不应仅折叠该序列的一部分,并且折叠后的序列不应存在剩余的相邻零段)。
  • 根据规范,如果存在最长的两个单独的等长零段序列,则仅应折叠第一个这样的序列。

目标 - IPv6 双栈:

  • 应允许已弃用的兼容语法。
  • 根据规范,应以六个零段的序列开始以实现兼容,并以五个零段的序列和一个 FFFF 段作为映射地址表示法开始。 (许多现有的解决方案都犯了这个错误。)
  • 最后折叠的序列 :: 省略应该是可选的(两种变体都应该允许)。

已经尝试过的模式

  • (([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))
    来自这里。虽然这甚至没有通过所有测试用例,但当前的测试用例集中还没有包含许多其他失败,例如多序列崩溃。
  • (?:(?:(?:[0-9A-Fa-f]{1,4}:){6}|::(?:[0-9A-Fa-f]{1,4}:){5}|(?:[0-9A-Fa-f]{1,4})?::(?:[0-9A-Fa-f]{1,4}:){4}|(?:(?:[0-9A-Fa-f]{1,4}:){0,1}[0-9A-Fa-f]{1,4})?::(?:[0-9A-Fa-f]{1,4}:){3}|(?:(?:[0-9A-Fa-f]{1,4}:){0,2}[0-9A-Fa-f]{1,4})?::(?:[0-9A-Fa-f]{1,4}:){2}|(?:(?:[0-9A-Fa-f]{1,4}:){0,3}[0-9A-Fa-f]{1,4})?::[0-9A-Fa-f]{1,4}:|(?:(?:[0-9A-Fa-f]{1,4}:){0,4}[0-9A-Fa-f]{1,4})?::)(?:[0-9A-Fa-f]{1,4}:[0-9A-Fa-f]{1,4}|(?:(?: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]?))|(?:(?:[0-9A-Fa-f]{1,4}:){0,5}[0-9A-Fa-f]{1,4})?::[0-9A-Fa-f]{1,4}|(?:(?:[0-9A-Fa-f]{1,4}:){0,6}[0-9A-Fa-f]{1,4})?::)
    来自这里
  • 还有许多其他...

测试用例

以下部分是基于这些得出的,但在许多情况下使用不同。

let ipv6Valid = [
    '0000:0000:0000:0000:0000:0000:0000:0000/128',
    '0000:0000:0000:0000:0000:0000:0000:0000',
    '0000:0000:0000:0000:0000:0000:0000:0001',
    '0:0:0:0:0:0:0:0',
    '0:0:0:0:0:0:0:1',
    '0:0:0:0:1:0:0:0',
    '0:1:2:3:4:5:6:7/128',
    '0:1:2:3:4:5:6:7',
    '1080:0:0:0:8:800:200c:417a',
    '1080::8:800:200c:417a',
    '1111:2222:3333:4444:5555:6666:7777:8888',
    '1111:2222:3333:4444:5555:6666::',
    '1111:2222:3333:4444:5555::',
    '1111:2222:3333:4444:5555::8888',
    '1111:2222:3333:4444::',
    '1111:2222:3333:4444::7777:8888',
    '1111:2222:3333:4444::8888',
    '1111:2222:3333::',
    '1111:2222:3333::6666:7777:8888',
    '1111:2222:3333::7777:8888',
    '1111:2222:3333::8888',
    '1111:2222::',
    '1111:2222::5555:6666:7777:8888',
    '1111:2222::6666:7777:8888',
    '1111:2222::7777:8888',
    '1111:2222::8888',
    '1111::',
    '1111::4444:5555:6666:7777:8888',
    '1111::5555:6666:7777:8888',
    '1111::6666:7777:8888',
    '1111::7777:8888',
    '1111::8888',
    '1:2:3:4:5:6:7:8',
    '1:2:3:4:5:6::',
    '1:2:3:4:5::',
    '1:2:3:4:5::8',
    '1:2:3:4::',
    '1:2:3:4::7:8',
    '1:2:3:4::8',
    '1:2:3::',
    '1:2:3::7:8',
    '1:2:3::8',
    '1:2::',
    '1:2::7:8',
    '1:2::8',
    '1::',
    '1::2:3',
    '1::2:3:4',
    '1::2:3:4:5',
    '1::2:3:4:5:6',
    '1::7:8',
    '1::8',
    '2001:0000:1234:0000:0000:C1C0:ABCD:0876',
    '2001:0000:4136:e378:8000:63bf:3fff:fdd2',
    '2001:0DB8:0000:CD30:0000:0000:0000:0000/60',
    '2001:DB8:0:CD30::/60',
    '2001:DB8:0:CD30/60',
    '2001:0db8:0000:0000:0000:0000:1428:57ab',
    '2001:0db8:0:0:0:0:1428:57ab',
    '2001:0db8:1234:0000:0000:0000:0000:0000',
    '2001:db8:1234::',
    '2001:0db8:1234:ffff:ffff:ffff:ffff:ffff',
    '2001:0db8:85a3:0000:0000:8a2e:0370:7334',
    '2001:db8::1428:57ab',
    '2001:DB8:0:0:8:800:200C:417A',
    '2001:DB8::8:800:200C:417A',
    '2001:db8:85a3:0:0:8a2e:370:7334',
    '2001:db8:85a3::8a2e:370:7334',
    '2001:db8::',
    '2001:db8::1428:57ab',
    '2001:db8:a::123',
    '2002::',
    '2608::3:5',
    '2608:af09:30:0:0:0:0:134',
    '2::10',
    '3ffe:0b00:0000:0000:0001:0000:0000:000a',
    '7:6:5:4:3:2:1:0',
    '::',
    '::/128',
    '::1',
    '::1/128',
    '::2:3',
    '::2:3:4',
    '::2:3:4:5',
    '::2:3:4:5:6',
    '::2:3:4:5:6:7',
    '::3333:4444:5555:6666:7777:8888',
    '::4444:5555:6666:7777:8888',
    '::5555:6666:7777:8888',
    '::6666:7777:8888',
    '::7777:8888',
    '::8',
    '::8888',
    '::ffff:0:0',
    '::ffff:c000:280',
    'FE80::/10',
    'FEC0::/10',
    'FF00::/8',
    'FF01:0:0:0:0:0:0:101',
    'FF01::101',
    'FF02:0000:0000:0000:0000:0000:0000:0001',
    'fe80:0000:0000:0000:0204:61ff:fe9d:f156',
    'fe80:0:0:0:204:61ff:fe9d:f156',
    'fe80::',
    'fe80::1',
    'fe80::204:61ff:fe9d:f156',
    'fe80::217:f2ff:fe07:ed62',
    'fedc:ba98:7654:3210:fedc:ba98:7654:3210',
    'ff02::1',
    'ffff::',
    'ffff::3:5',
    'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff',
]
let ipv6Invalid = [
    '1:0:0:0:1::1',
    '10.0.0.1',
    '-1',
    '::1 ::1',
    '02001:0000:1234:0000:0000:C1C0:ABCD:0876',
    '1.2.3.4',
    '1.2.3.4:1111:2222:3333:4444::5555',
    '1.2.3.4:1111:2222:3333::5555',
    '1.2.3.4:1111:2222::5555',
    '1.2.3.4:1111::5555',
    '1.2.3.4::',
    '1.2.3.4::5555',
    '1111',
    '11112222:3333:4444:5555:6666:1.2.3.4',
    '11112222:3333:4444:5555:6666:7777:8888',
    '::1//64',
    '::1/0001',
    '1111:',
    '1111:1.2.3.4',
    '1111:2222',
    '1111:22223333:4444:5555:6666:1.2.3.4',
    '1111:22223333:4444:5555:6666:7777:8888',
    '1111:2222:',
    '1111:2222:1.2.3.4',
    '1111:2222:3333',
    '1111:2222:33334444:5555:6666:1.2.3.4',
    '1111:2222:33334444:5555:6666:7777:8888',
    '1111:2222:3333:',
    '1111:2222:3333:1.2.3.4',
    '1111:2222:3333:4444',
    '1111:2222:3333:44445555:6666:1.2.3.4',
    '1111:2222:3333:44445555:6666:7777:8888',
    '1111:2222:3333:4444:',
    '1111:2222:3333:4444:1.2.3.4',
    '1111:2222:3333:4444:5555',
    '1111:2222:3333:4444:55556666:1.2.3.4',
    '1111:2222:3333:4444:55556666:7777:8888',
    '1111:2222:3333:4444:5555:',
    '1111:2222:3333:4444:5555:1.2.3.4',
    '1111:2222:3333:4444:5555:6666',
    '1111:2222:3333:4444:5555:66661.2.3.4',
    '1111:2222:3333:4444:5555:66667777:8888',
    '1111:2222:3333:4444:5555:6666:',
    '1111:2222:3333:4444:5555:6666:00.00.00.00',
    '1111:2222:3333:4444:5555:6666:000.000.000.000',
    '1111:2222:3333:4444:5555:6666:1.2.3.4.5',
    '1111:2222:3333:4444:5555:6666:255.255.255255',
    '1111:2222:3333:4444:5555:6666:255.255255.255',
    '1111:2222:3333:4444:5555:6666:255255.255.255',
    '1111:2222:3333:4444:5555:6666:256.256.256.256',
    '1111:2222:3333:4444:5555:6666:7777',
    '1111:2222:3333:4444:5555:6666:77778888',
    '1111:2222:3333:4444:5555:6666:7777:',
    '1111:2222:3333:4444:5555:6666:7777:1.2.3.4',
    '1111:2222:3333:4444:5555:6666:7777:8888:',
    '1111:2222:3333:4444:5555:6666:7777:8888:1.2.3.4',
    '1111:2222:3333:4444:5555:6666:7777:8888:9999',
    '1111:2222:3333:4444:5555:6666:7777:8888::',
    '1111:2222:3333:4444:5555:6666:7777:::',
    '1111:2222:3333:4444:5555:6666::1.2.3.4',
    '1111:2222:3333:4444:5555:6666::8888:',
    '1111:2222:3333:4444:5555:6666:::',
    '1111:2222:3333:4444:5555:6666:::8888',
    '1111:2222:3333:4444:5555::7777:8888:',
    '1111:2222:3333:4444:5555::7777::',
    '1111:2222:3333:4444:5555::8888:',
    '1111:2222:3333:4444:5555:::',
    '1111:2222:3333:4444:5555:::1.2.3.4',
    '1111:2222:3333:4444:5555:::7777:8888',
    '1111:2222:3333:4444::5555:',
    '1111:2222:3333:4444::6666:7777:8888:',
    '1111:2222:3333:4444::6666:7777::',
    '1111:2222:3333:4444::6666::8888',
    '1111:2222:3333:4444::7777:8888:',
    '1111:2222:3333:4444::8888:',
    '1111:2222:3333:4444:::',
    '1111:2222:3333:4444:::6666:1.2.3.4',
    '1111:2222:3333:4444:::6666:7777:8888',
    '1111:2222:3333::5555:',
    '1111:2222:3333::5555:6666:7777:8888:',
    '1111:2222:3333::5555:6666:7777::',
    '1111:2222:3333::5555:6666::8888',
    '1111:2222:3333::5555::1.2.3.4',
    '1111:2222:3333::5555::7777:8888',
    '1111:2222:3333::6666:7777:8888:',
    '1111:2222:3333::7777:8888:',
    '1111:2222:3333::8888:',
    '1111:2222:3333:::',
    '1111:2222:3333:::5555:6666:1.2.3.4',
    '1111:2222:3333:::5555:6666:7777:8888',
    '1111:2222::4444:5555:6666:7777:8888:',
    '1111:2222::4444:5555:6666:7777::',
    '1111:2222::4444:5555:6666::8888',
    '1111:2222::4444:5555::1.2.3.4',
    '1111:2222::4444:5555::7777:8888',
    '1111:2222::4444::6666:1.2.3.4',
    '1111:2222::4444::6666:7777:8888',
    '1111:2222::5555:',
    '1111:2222::5555:6666:7777:8888:',
    '1111:2222::6666:7777:8888:',
    '1111:2222::7777:8888:',
    '1111:2222::8888:',
    '1111:2222:::',
    '1111:2222:::4444:5555:6666:1.2.3.4',
    '1111:2222:::4444:5555:6666:7777:8888',
    '1111::3333:4444:5555:6666:7777:8888:',
    '1111::3333:4444:5555:6666:7777::',
    '1111::3333:4444:5555:6666::8888',
    '1111::3333:4444:5555::1.2.3.4',
    '1111::3333:4444:5555::7777:8888',
    '1111::3333:4444::6666:1.2.3.4',
    '1111::3333:4444::6666:7777:8888',
    '1111::3333::5555:6666:1.2.3.4',
    '1111::3333::5555:6666:7777:8888',
    '1111::4444:5555:6666:7777:8888:',
    '1111::5555:',
    '1111::5555:6666:7777:8888:',
    '1111::6666:7777:8888:',
    '1111::7777:8888:',
    '1111::8888:',
    '1111:::',
    '1111:::3333:4444:5555:6666:1.2.3.4',
    '1111:::3333:4444:5555:6666:7777:8888',
    '123',
    '12345::6:7:8',
    '124.15.6.89/60',
    '1:2:3:4:5:6:7:8:9',
    '1:2:3::4:5:6:7:8:9',
    '1:2:3::4:5::7:8',
    '1::1.2.256.4',
    '1::1.2.3.256',
    '1::1.2.3.300',
    '1::1.2.3.900',
    '1::1.2.300.4',
    '1::1.2.900.4',
    '1::1.256.3.4',
    '1::1.300.3.4',
    '1::1.900.3.4',
    '1::256.2.3.4',
    '1::260.2.3.4',
    '1::2::3',
    '1::300.2.3.4',
    '1::300.300.300.300',
    '1::3000.30.30.30',
    '1::400.2.3.4',
    '1::5:1.2.256.4',
    '1::5:1.2.3.256',
    '1::5:1.2.3.300',
    '1::5:1.2.3.900',
    '1::5:1.2.300.4',
    '1::5:1.2.900.4',
    '1::5:1.256.3.4',
    '1::5:1.300.3.4',
    '1::5:1.900.3.4',
    '1::5:256.2.3.4',
    '1::5:260.2.3.4',
    '1::5:300.2.3.4',
    '1::5:300.300.300.300',
    '1::5:3000.30.30.30',
    '1::5:400.2.3.4',
    '1::5:900.2.3.4',
    '1::900.2.3.4',
    '1:::3:4:5',
    '2001:0000:1234: 0000:0000:C1C0:ABCD:0876',
    '2001:0000:1234:0000:00001:C1C0:ABCD:0876',
    '2001:0000:1234:0000:0000:C1C0:ABCD:0876  0',
    '2001:1:1:1:1:1:255Z255X255Y255',
    '2001::FFD3::57ab',
    '2001:DB8:0:0:8:800:200C:417A:221',
    '2001:db8:85a3::8a2e:37023:7334',
    '2001:db8:85a3::8a2e:370k:7334',
    '3ffe:0b00:0000:0001:0000:0000:000a',
    '3ffe:b00::1::a',
    ':',
    ':1.2.3.4',
    ':1111:2222:3333:4444:5555:6666:1.2.3.4',
    ':1111:2222:3333:4444:5555:6666:7777:8888',
    ':1111:2222:3333:4444:5555:6666:7777::',
    ':1111:2222:3333:4444:5555:6666::',
    ':1111:2222:3333:4444:5555:6666::8888',
    ':1111:2222:3333:4444:5555::',
    ':1111:2222:3333:4444:5555::1.2.3.4',
    ':1111:2222:3333:4444:5555::7777:8888',
    ':1111:2222:3333:4444:5555::8888',
    ':1111:2222:3333:4444::',
    ':1111:2222:3333:4444::1.2.3.4',
    ':1111:2222:3333:4444::5555',
    ':1111:2222:3333:4444::6666:1.2.3.4',
    ':1111:2222:3333:4444::6666:7777:8888',
    ':1111:2222:3333:4444::7777:8888',
    ':1111:2222:3333:4444::8888',
    ':1111:2222:3333::',
    ':1111:2222:3333::1.2.3.4',
    ':1111:2222:3333::5555',
    ':1111:2222:3333::5555:6666:1.2.3.4',
    ':1111:2222:3333::5555:6666:7777:8888',
    ':1111:2222:3333::6666:1.2.3.4',
    ':1111:2222:3333::6666:7777:8888',
    ':1111:2222:3333::7777:8888',
    ':1111:2222:3333::8888',
    ':1111:2222::',
    ':1111:2222::1.2.3.4',
    ':1111:2222::4444:5555:6666:1.2.3.4',
    ':1111:2222::4444:5555:6666:7777:8888',
    ':1111:2222::5555',
    ':1111:2222::5555:6666:1.2.3.4',
    ':1111:2222::5555:6666:7777:8888',
    ':1111:2222::6666:1.2.3.4',
    ':1111:2222::6666:7777:8888',
    ':1111:2222::7777:8888',
    ':1111:2222::8888',
    ':1111::',
    ':1111::1.2.3.4',
    ':1111::3333:4444:5555:6666:1.2.3.4',
    ':1111::3333:4444:5555:6666:7777:8888',
    ':1111::4444:5555:6666:1.2.3.4',
    ':1111::4444:5555:6666:7777:8888',
    ':1111::5555',
    ':1111::5555:6666:1.2.3.4',
    ':1111::5555:6666:7777:8888',
    ':1111::6666:1.2.3.4',
    ':1111::6666:7777:8888',
    ':1111::7777:8888',
    ':1111::8888',
    ':2222:3333:4444:5555:6666:1.2.3.4',
    ':2222:3333:4444:5555:6666:7777:8888',
    ':3333:4444:5555:6666:1.2.3.4',
    ':3333:4444:5555:6666:7777:8888',
    ':4444:5555:6666:1.2.3.4',
    ':4444:5555:6666:7777:8888',
    ':5555:6666:1.2.3.4',
    ':5555:6666:7777:8888',
    ':6666:1.2.3.4',
    ':6666:7777:8888',
    ':7777:8888',
    ':8888',
    '::-1',
    '::.',
    '::..',
    '::...',
    '::...4',
    '::..3.',
    '::..3.4',
    '::.2..',
    '::.2.3.',
    '::.2.3.4',
    '::1...',
    '::1.2..',
    '::1.2.256.4',
    '::1.2.3.',
    '::1.2.3.256',
    '::1.2.3.300',
    '::1.2.3.900',
    '::1.2.300.4',
    '::1.2.900.4',
    '::1.256.3.4',
    '::1.300.3.4',
    '::1.900.3.4',
    '::1111:2222:3333:4444:5555:6666::',
    '::2222:3333:4444:5555:6666:7777:1.2.3.4',
    '::2222:3333:4444:5555:6666:7777:8888:',
    '::2222:3333:4444:5555:6666:7777:8888:9999',
    '::2222:3333:4444:5555:7777:8888::',
    '::2222:3333:4444:5555:7777::8888',
    '::2222:3333:4444:5555::1.2.3.4',
    '::2222:3333:4444:5555::7777:8888',
    '::2222:3333:4444::6666:1.2.3.4',
    '::2222:3333:4444::6666:7777:8888',
    '::2222:3333::5555:6666:1.2.3.4',
    '::2222:3333::5555:6666:7777:8888',
    '::2222::4444:5555:6666:1.2.3.4',
    '::2222::4444:5555:6666:7777:8888',
    '::256.2.3.4',
    '::260.2.3.4',
    '::300.2.3.4',
    '::300.300.300.300',
    '::3000.30.30.30',
    '::3333:4444:5555:6666:7777:8888:',
    '::400.2.3.4',
    '::4444:5555:6666:7777:8888:',
    '::5555:',
    '::5555:6666:7777:8888:',
    '::6666:7777:8888:',
    '::7777:8888:',
    '::8888:',
    '::900.2.3.4',
    ':::',
    ':::1.2.3.4',
    ':::2222:3333:4444:5555:6666:1.2.3.4',
    ':::2222:3333:4444:5555:6666:7777:8888',
    ':::3333:4444:5555:6666:7777:8888',
    ':::4444:5555:6666:1.2.3.4',
    ':::4444:5555:6666:7777:8888',
    ':::5555',
    ':::5555:6666:1.2.3.4',
    ':::5555:6666:7777:8888',
    ':::6666:1.2.3.4',
    ':::6666:7777:8888',
    ':::7777:8888',
    ':::8888',
    '::ffff:192x168.1.26',
    '::ffff:2.3.4',
    '::ffff:257.1.2.3',
    'FF01::101::2',
    'FF02:0000:0000:0000:0000:0000:0000:0000:0001',
    'XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:1.2.3.4',
    'XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX',
    'a::b::c',
    'a::g',
    'a:a:a:a:a:a:a:a:a',
    'a:aaaaa::',
    'a:b',
    'a:b:c:d:e:f:g:0',
    'fe80:0000:0000:0000:0204:61ff:254.157.241.086',
    'ffff:',
    'ffff::ffff::ffff',
    'ffgg:ffff:ffff:ffff:ffff:ffff:ffff:ffff',
    'ldkfj',
    '::/129',
    '1000:://32',
    '::/',
    '0:0:0:0:0:0:0::',
    '0:0:0:0:0:0::',
    '0:0:0:0:0::',
    '0:0:0:0::',
    '0:0:0::',
    '0:0::',
    '0::',
    '0:a:b:c:d:e:f::',
    '1111:2222:3333:4444:5555:6666:123.123.123.123',
    '1111:2222:3333:4444:5555:6666:7777::',
    '1111:2222:3333:4444:5555:6666::8888',
    '1111:2222:3333:4444:5555::123.123.123.123',
    '1111:2222:3333:4444:5555::7777:8888',
    '1111:2222:3333:4444::6666:7777:8888',
    '1111:2222:3333::5555:6666:7777:8888',
    '1111:2222::4444:5555:6666:7777:8888',
    '1111::3333:4444:5555:6666:7777:8888',
    '::2222:3333:4444:5555:6666:7777:8888',
    '1:2:3:4:5:6::8',
    '1:2:3:4:5::7:8',
    '1::2:3:4:5:6:7',
    '2001:0db8:0000:0000:0000::1428:57ab',
    '2001::CE49:7601:2CAD:DFFF:7C94:FFFE',
    '2001::CE49:7601:E866:EFFF:62C3:FFFE',
    '2608:af09:30::102a:7b91:c239:baff',
    '::0',
    '::0:0',
    '::0:0:0',
    '::0:0:0:0',
    '::0:0:0:0:0',
    '::0:0:0:0:0:0',
    '::0:0:0:0:0:0:0',
    '::0:a:b:c:d:e:f',
    'a:b:c:d:e:f:0::',
    'a:0::0:b',
    'a:0:0::0:b',
    'a:0::0:0:b',
    'a::0:0:b',
    'a::0:b',
    'a:0::b',
    'a:0:0::b',
    '::ffff:0c22:384e',
    '::2:3:4:5:6:7:8',
    '2001:0DB8::CD30:0:0:0:0/60',
    '2001:0db8:0:0::1428:57ab',
    '0:1:2:3:4:5:6:7/001',
]

测试用例 - 双栈

let ipv6HybridValid = [
    '0:0:0:0:0:0:13.1.68.3',
    '0:0:0:0:0:FFFF:129.144.52.38',
    '::FFFF:129.144.52.38',
    '::ffff:12.34.56.78',
    '::ffff:192.0.2.128',
    '::ffff:192.168.1.1',
    '::ffff:192.168.1.26',
    '::123.123.123.123',
    '::13.1.68.3',
]
let ipv6HybridInvalid = [
    '1111:2222:3333:4444:5555::123.123.123.123',
    '1111:2222:3333:4444::123.123.123.123',
    '1111:2222:3333:4444::6666:123.123.123.123',
    '1111:2222:3333::123.123.123.123',
    '1111:2222:3333::5555:6666:123.123.123.123',
    '1111:2222:3333::6666:123.123.123.123',
    '1111:2222::123.123.123.123',
    '1111:2222::4444:5555:6666:123.123.123.123',
    '1111:2222::5555:6666:123.123.123.123',
    '1111:2222::6666:123.123.123.123',
    '1111::123.123.123.123',
    '1111::3333:4444:5555:6666:123.123.123.123',
    '1111::4444:5555:6666:123.123.123.123',
    '1111::5555:6666:123.123.123.123',
    '1111::6666:123.123.123.123',
    '1:2:3:4:5:6:1.2.3.4',
    '1:2:3:4:5::1.2.3.4',
    '1:2:3:4::1.2.3.4',
    '1:2:3:4::5:1.2.3.4',
    '1:2:3::1.2.3.4',
    '1:2:3::5:1.2.3.4',
    '1:2::1.2.3.4',
    '1:2::5:1.2.3.4',
    '1::1.2.3.4',
    '1::5:1.2.3.4',
    '1::5:11.22.33.44',
    '::4444:5555:6666:123.123.123.123',
    '::5555:6666:123.123.123.123',
    '::6666:123.123.123.123',
    'fe80:0:0:0:204:61ff:254.157.241.86',
    'fe80::204:61ff:254.157.241.86',
    'fe80::217:f2ff:254.7.237.98',
]

我可能错过了上面提到的一些要点/目标,但如果我注意到这些,我会尝试编辑和更新。

如果对要求有任何不清楚的地方,请在评论中询问。

我已经编写了一个复杂的正则表达式来尝试实现这些目标,但是尤其是。由于测试用例不完整,我仍然不确定目标是否实现。我将尝试将我的解决方案作为答案发布在下面,供遇到与我相同问题的任何人使用。

这个问题本来是一个问答对(自我回答),但我也在向社区询问测试用例和我自己的解决方案的正确性。

如果在发布后发现任何错误/勘误表/问题,我将尝试相应地更新我的问题和答案,尝试解决这些问题。

javascript regex validation ipv6 ipv4
1个回答
0
投票

这个解决方案似乎满足了我的大部分要求,但它还没有经过广泛和彻底的测试,但它通过了我可以扔给它的大部分测试用例。

细分符号

[01]{8}
|
::1(
    1?[01]{0,3}
    |
    01[01]{0,2}
    |
    001[01]?
    |
    0001
    |
    (?!000)[01](?!000)[01](?!000)[01]{3}
)
|
(
    1::1(
        1?[01]{0,3}
        |
        01[01]{0,2}
        |
        001[01]?
    )
    |
    [01]1::1(
        1?[01]{0,2}
        |
        01[01]?
        |
        001
    )
    |
    [01]{1,2}1::1(1[01]|[01]1)
    |
    (1[01]|[01]1)1::1[01]{1,2}
    |
    [01]1[01]1::1[01]?
    |
    (
        1?[01]{1,2}
        |
        01([01]?|11)
        |
        001
        |
        1011
        |
        1101
        |
        1110
        |
        1111
    )1::1
)
|
(
    1?[01]{0,3}
    |
    01[01]{0,2}
    |
    001[01]?
    |
    0001
    |
    (?!000)[01](?!000)[01](?!000)[01]{3}
)1::

正则表达式分解

(
    ([1-9A-Fa-f][0-9A-Fa-f]{0,3}|0|[0-9A-Fa-f]{4})(:[1-9A-Fa-f][0-9A-Fa-f]{0,3}|:0|:[0-9A-Fa-f]{4}){7}|
    ::(
        [1-9A-Fa-f][0-9A-Fa-f]{0,3}(
            (:[1-9A-Fa-f][0-9A-Fa-f]{0,3})?(:[1-9A-Fa-f][0-9A-Fa-f]{0,3}|:0){0,3}|
            :0:(
                [1-9A-Fa-f][0-9A-Fa-f]{0,3}(:[1-9A-Fa-f][0-9A-Fa-f]{0,3}|:0){0,2}
                0:(
                    [1-9A-Fa-f][0-9A-Fa-f]{0,3}(:[1-9A-Fa-f][0-9A-Fa-f]{0,3}|:0)?
                    0:[1-9A-Fa-f][0-9A-Fa-f]{0,3}
                )
            )|
            (?!:0:0:0):([1-9A-Fa-f][0-9A-Fa-f]{0,3}|0)
            (?!:0:0:0):([1-9A-Fa-f][0-9A-Fa-f]{0,3}|0)
            (?!:0:0:0)(:[1-9A-Fa-f][0-9A-Fa-f]{0,3}|:0){3}
        )
    )?|
        [1-9A-Fa-f][0-9A-Fa-f]{0,3}::[1-9A-Fa-f][0-9A-Fa-f]{0,3}(
            (:[1-9A-Fa-f][0-9A-Fa-f]{0,3})?(:[1-9A-Fa-f][0-9A-Fa-f]{0,3}|:0){0,3}|
            :0:(
                [1-9A-Fa-f][0-9A-Fa-f]{0,3}(:[1-9A-Fa-f][0-9A-Fa-f]{0,3}|:0){0,2}|
                0:[1-9A-Fa-f][0-9A-Fa-f]{0,3}(:[1-9A-Fa-f][0-9A-Fa-f]{0,3}|:0)?
            )
        )|
        ([1-9A-Fa-f][0-9A-Fa-f]{0,3}|0):[1-9A-Fa-f][0-9A-Fa-f]{0,3}::[1-9A-Fa-f][0-9A-Fa-f]{0,3}(
            (:[1-9A-Fa-f][0-9A-Fa-f]{0,3})?(:[1-9A-Fa-f][0-9A-Fa-f]{0,3}|:0){0,2}|
            :0:(
                [1-9A-Fa-f][0-9A-Fa-f]{0,3}(:[1-9A-Fa-f][0-9A-Fa-f]{0,3}|:0)?|
                0:[1-9A-Fa-f][0-9A-Fa-f]{0,3}
            )
        )|
        ([1-9A-Fa-f][0-9A-Fa-f]{0,3}:|0:){1,2}[1-9A-Fa-f][0-9A-Fa-f]{0,3}::[1-9A-Fa-f][0-9A-Fa-f]{0,3}:
        (
            [1-9A-Fa-f][0-9A-Fa-f]{0,3}:([1-9A-Fa-f][0-9A-Fa-f]{0,3}|0)|
            ([1-9A-Fa-f][0-9A-Fa-f]{0,3}|0):[1-9A-Fa-f][0-9A-Fa-f]{0,3}
        )|
        (
            [1-9A-Fa-f][0-9A-Fa-f]{0,3}:([1-9A-Fa-f][0-9A-Fa-f]{0,3}|0)|
            ([1-9A-Fa-f][0-9A-Fa-f]{0,3}|0):[1-9A-Fa-f][0-9A-Fa-f]{0,3}
        ):
        [1-9A-Fa-f][0-9A-Fa-f]{0,3}::[1-9A-Fa-f][0-9A-Fa-f]{0,3}(:[1-9A-Fa-f][0-9A-Fa-f]{0,3}|:0){1,2}|
        ([1-9A-Fa-f][0-9A-Fa-f]{0,3}|0):[1-9A-Fa-f][0-9A-Fa-f]{0,3}:([1-9A-Fa-f][0-9A-Fa-f]{0,3}|0):
        [1-9A-Fa-f][0-9A-Fa-f]{0,3}::[1-9A-Fa-f][0-9A-Fa-f]{0,3}(:[1-9A-Fa-f][0-9A-Fa-f]{0,3}|:0)?|
        (
            ([1-9A-Fa-f][0-9A-Fa-f]{0,3}:)?([1-9A-Fa-f][0-9A-Fa-f]{0,3}:|0:){0,2}|
            0:(
                [1-9A-Fa-f][0-9A-Fa-f]{0,3}(
                    ([1-9A-Fa-f][0-9A-Fa-f]{0,3}|0)|
                    (:[1-9A-Fa-f][0-9A-Fa-f]{0,3}){2}
                |)|
                0:[1-9A-Fa-f][0-9A-Fa-f]{0,3}
            ):|
            [1-9A-Fa-f][0-9A-Fa-f]{0,3}:(
                0(:[1-9A-Fa-f][0-9A-Fa-f]{0,3}){2}|
                [1-9A-Fa-f][0-9A-Fa-f]{0,3}:(
                    0:[1-9A-Fa-f][0-9A-Fa-f]{0,3}|
                    [1-9A-Fa-f][0-9A-Fa-f]{0,3}:(
                        0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}
                    )
                )
            ):
        )[1-9A-Fa-f][0-9A-Fa-f]{0,3}::[1-9A-Fa-f][0-9A-Fa-f]{0,3}
    |(
        (
            ([1-9A-Fa-f][0-9A-Fa-f]{0,3}:)?([1-9A-Fa-f][0-9A-Fa-f]{0,3}:|0:){0,3}|
            0:(
                [1-9A-Fa-f][0-9A-Fa-f]{0,3}(:[1-9A-Fa-f][0-9A-Fa-f]{0,3}|:0){0,2}|
                0:(
                    [1-9A-Fa-f][0-9A-Fa-f]{0,3}(:[1-9A-Fa-f][0-9A-Fa-f]{0,3}|:0)?|
                    0:[1-9A-Fa-f][0-9A-Fa-f]{0,3}
                )
            ):|
            (?!0:0:0)([1-9A-Fa-f][0-9A-Fa-f]{0,3}|0):
            (?!0:0:0)([1-9A-Fa-f][0-9A-Fa-f]{0,3}|0):
            (?!0:0:0)([1-9A-Fa-f][0-9A-Fa-f]{0,3}:|0:){3}
        )[1-9A-Fa-f][0-9A-Fa-f]{0,3}
    )(::|(?=\/))
)(\/(12[0-8]|(11|[1-9]|)[0-9]))?

单线

注意:这已针对 JavaScript 进行了格式化,但经过细微修改后,可能会进行调整。

^(([1-9A-Fa-f][0-9A-Fa-f]{0,3}|0|[0-9A-Fa-f]{4})(:[1-9A-Fa-f][0-9A-Fa-f]{0,3}|:0|:[0-9A-Fa-f]{4}){7}|::([1-9A-Fa-f][0-9A-Fa-f]{0,3}((:[1-9A-Fa-f][0-9A-Fa-f]{0,3})?(:[1-9A-Fa-f][0-9A-Fa-f]{0,3}|:0){0,3}|:0:([1-9A-Fa-f][0-9A-Fa-f]{0,3}(:[1-9A-Fa-f][0-9A-Fa-f]{0,3}|:0){0,2}0:([1-9A-Fa-f][0-9A-Fa-f]{0,3}(:[1-9A-Fa-f][0-9A-Fa-f]{0,3}|:0)?0:[1-9A-Fa-f][0-9A-Fa-f]{0,3}))|(?!:0:0:0):([1-9A-Fa-f][0-9A-Fa-f]{0,3}|0)(?!:0:0:0):([1-9A-Fa-f][0-9A-Fa-f]{0,3}|0)(?!:0:0:0)(:[1-9A-Fa-f][0-9A-Fa-f]{0,3}|:0){3}))?|[1-9A-Fa-f][0-9A-Fa-f]{0,3}::[1-9A-Fa-f][0-9A-Fa-f]{0,3}((:[1-9A-Fa-f][0-9A-Fa-f]{0,3})?(:[1-9A-Fa-f][0-9A-Fa-f]{0,3}|:0){0,3}|:0:([1-9A-Fa-f][0-9A-Fa-f]{0,3}(:[1-9A-Fa-f][0-9A-Fa-f]{0,3}|:0){0,2}|0:[1-9A-Fa-f][0-9A-Fa-f]{0,3}(:[1-9A-Fa-f][0-9A-Fa-f]{0,3}|:0)?))|([1-9A-Fa-f][0-9A-Fa-f]{0,3}|0):[1-9A-Fa-f][0-9A-Fa-f]{0,3}::[1-9A-Fa-f][0-9A-Fa-f]{0,3}((:[1-9A-Fa-f][0-9A-Fa-f]{0,3})?(:[1-9A-Fa-f][0-9A-Fa-f]{0,3}|:0){0,2}|:0:([1-9A-Fa-f][0-9A-Fa-f]{0,3}(:[1-9A-Fa-f][0-9A-Fa-f]{0,3}|:0)?|0:[1-9A-Fa-f][0-9A-Fa-f]{0,3}))|([1-9A-Fa-f][0-9A-Fa-f]{0,3}:|0:){1,2}[1-9A-Fa-f][0-9A-Fa-f]{0,3}::[1-9A-Fa-f][0-9A-Fa-f]{0,3}:([1-9A-Fa-f][0-9A-Fa-f]{0,3}:([1-9A-Fa-f][0-9A-Fa-f]{0,3}|0)|([1-9A-Fa-f][0-9A-Fa-f]{0,3}|0):[1-9A-Fa-f][0-9A-Fa-f]{0,3})|([1-9A-Fa-f][0-9A-Fa-f]{0,3}:([1-9A-Fa-f][0-9A-Fa-f]{0,3}|0)|([1-9A-Fa-f][0-9A-Fa-f]{0,3}|0):[1-9A-Fa-f][0-9A-Fa-f]{0,3}):[1-9A-Fa-f][0-9A-Fa-f]{0,3}::[1-9A-Fa-f][0-9A-Fa-f]{0,3}(:[1-9A-Fa-f][0-9A-Fa-f]{0,3}|:0){1,2}|([1-9A-Fa-f][0-9A-Fa-f]{0,3}|0):[1-9A-Fa-f][0-9A-Fa-f]{0,3}:([1-9A-Fa-f][0-9A-Fa-f]{0,3}|0):[1-9A-Fa-f][0-9A-Fa-f]{0,3}::[1-9A-Fa-f][0-9A-Fa-f]{0,3}(:[1-9A-Fa-f][0-9A-Fa-f]{0,3}|:0)?|(([1-9A-Fa-f][0-9A-Fa-f]{0,3}:)?([1-9A-Fa-f][0-9A-Fa-f]{0,3}:|0:){0,2}|0:([1-9A-Fa-f][0-9A-Fa-f]{0,3}(([1-9A-Fa-f][0-9A-Fa-f]{0,3}|0)|(:[1-9A-Fa-f][0-9A-Fa-f]{0,3}){2}|)|0:[1-9A-Fa-f][0-9A-Fa-f]{0,3}):|[1-9A-Fa-f][0-9A-Fa-f]{0,3}:(0(:[1-9A-Fa-f][0-9A-Fa-f]{0,3}){2}|[1-9A-Fa-f][0-9A-Fa-f]{0,3}:(0:[1-9A-Fa-f][0-9A-Fa-f]{0,3}|[1-9A-Fa-f][0-9A-Fa-f]{0,3}:(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))):)[1-9A-Fa-f][0-9A-Fa-f]{0,3}::[1-9A-Fa-f][0-9A-Fa-f]{0,3}|((([1-9A-Fa-f][0-9A-Fa-f]{0,3}:)?([1-9A-Fa-f][0-9A-Fa-f]{0,3}:|0:){0,3}|0:([1-9A-Fa-f][0-9A-Fa-f]{0,3}(:[1-9A-Fa-f][0-9A-Fa-f]{0,3}|:0){0,2}|0:([1-9A-Fa-f][0-9A-Fa-f]{0,3}(:[1-9A-Fa-f][0-9A-Fa-f]{0,3}|:0)?|0:[1-9A-Fa-f][0-9A-Fa-f]{0,3})):|(?!0:0:0)([1-9A-Fa-f][0-9A-Fa-f]{0,3}|0):(?!0:0:0)([1-9A-Fa-f][0-9A-Fa-f]{0,3}|0):(?!0:0:0)([1-9A-Fa-f][0-9A-Fa-f]{0,3}:|0:){3})[1-9A-Fa-f][0-9A-Fa-f]{0,3})(::|(?=\/)))(\/(12[0-8]|(11|[1-9]|)[0-9]))?$

© www.soinside.com 2019 - 2024. All rights reserved.