与正确的IPv6地址匹配的正则表达式

Rea*_*nly 112 regex networking ipv6

我在编写匹配有效IPv6地址的正则表达式时遇到问题,包括压缩形式的那些(::从每个字节对中省略或前导零).

有人可以建议一个符合要求的正则表达式吗?

我正在考虑扩展每个字节对,并将结果与​​更简单的正则表达式进行匹配.

Dav*_*dek 233

我无法得到@Factor Mystic使用POSIX正则表达式的答案,所以我写了一个与POSIX正则表达式和PERL正则表达式一起使用的答案.

它应该匹配:

IPv6正则表达式:

(([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]))
Run Code Online (Sandbox Code Playgroud)

为便于阅读,以下是将主要OR点分割成单独行的上述正则表达式:

# IPv6 RegEx
(
([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|          # 1:2:3:4:5:6:7:8
([0-9a-fA-F]{1,4}:){1,7}:|                         # 1::                              1:2:3:4:5:6:7::
([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|         # 1::8             1:2:3:4:5:6::8  1:2:3:4:5:6::8
([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|  # 1::7:8           1:2:3:4:5::7:8  1:2:3:4:5::8
([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|  # 1::6:7:8         1:2:3:4::6:7:8  1:2:3:4::8
([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|  # 1::5:6:7:8       1:2:3::5:6:7:8  1:2:3::8
([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|  # 1::4:5:6:7:8     1:2::4:5:6:7:8  1:2::8
[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|       # 1::3:4:5:6:7:8   1::3:4:5:6:7:8  1::8  
:((:[0-9a-fA-F]{1,4}){1,7}|:)|                     # ::2:3:4:5:6:7:8  ::2:3:4:5:6:7:8 ::8       ::     
fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|     # fe80::7:8%eth0   fe80::7:8%1     (link-local IPv6 addresses with zone index)
::(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])|          # ::255.255.255.255   ::ffff:255.255.255.255  ::ffff:0:255.255.255.255  (IPv4-mapped IPv6 addresses and IPv4-translated addresses)
([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])           # 2001:db8:3:4::192.0.2.33  64:ff9b::192.0.2.33 (IPv4-Embedded IPv6 Address)
)

# IPv4 RegEx
((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])
Run Code Online (Sandbox Code Playgroud)

为了使上述内容更容易理解,以下"伪"代码复制了上述内容:

IPV4SEG  = (25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])
IPV4ADDR = (IPV4SEG\.){3,3}IPV4SEG
IPV6SEG  = [0-9a-fA-F]{1,4}
IPV6ADDR = (
           (IPV6SEG:){7,7}IPV6SEG|                # 1:2:3:4:5:6:7:8
           (IPV6SEG:){1,7}:|                      # 1::                                 1:2:3:4:5:6:7::
           (IPV6SEG:){1,6}:IPV6SEG|               # 1::8               1:2:3:4:5:6::8   1:2:3:4:5:6::8
           (IPV6SEG:){1,5}(:IPV6SEG){1,2}|        # 1::7:8             1:2:3:4:5::7:8   1:2:3:4:5::8
           (IPV6SEG:){1,4}(:IPV6SEG){1,3}|        # 1::6:7:8           1:2:3:4::6:7:8   1:2:3:4::8
           (IPV6SEG:){1,3}(:IPV6SEG){1,4}|        # 1::5:6:7:8         1:2:3::5:6:7:8   1:2:3::8
           (IPV6SEG:){1,2}(:IPV6SEG){1,5}|        # 1::4:5:6:7:8       1:2::4:5:6:7:8   1:2::8
           IPV6SEG:((:IPV6SEG){1,6})|             # 1::3:4:5:6:7:8     1::3:4:5:6:7:8   1::8
           :((:IPV6SEG){1,7}|:)|                  # ::2:3:4:5:6:7:8    ::2:3:4:5:6:7:8  ::8       ::       
           fe80:(:IPV6SEG){0,4}%[0-9a-zA-Z]{1,}|  # fe80::7:8%eth0     fe80::7:8%1  (link-local IPv6 addresses with zone index)
           ::(ffff(:0{1,4}){0,1}:){0,1}IPV4ADDR|  # ::255.255.255.255  ::ffff:255.255.255.255  ::ffff:0:255.255.255.255 (IPv4-mapped IPv6 addresses and IPv4-translated addresses)
           (IPV6SEG:){1,4}:IPV4ADDR               # 2001:db8:3:4::192.0.2.33  64:ff9b::192.0.2.33 (IPv4-Embedded IPv6 Address)
           )
Run Code Online (Sandbox Code Playgroud)

我在GitHub上发布了一个测试正则表达式的脚本:https://gist.github.com/syzdek/6086792

  • IPv4段不应包含前导零.如果存在前导零,则应以八进制解释IPv4段.所以上面的IPV4SEG是正确的,不允许'000'.然而它确实允许'00',它不应该. (14认同)
  • 梦幻般的ipv6正则表达式.发现链接本地部分的一个小bug.你有`fe80`它应该像`[fF] [eE] 80`和`ffff`这样的东西应该像`[fF] {4} (5认同)
  • 您的IPv4正则表达式与`127.000.000.001`等IP不匹配 (3认同)
  • 我没想到会在浏览器中为我工作.验证甚至reg.test('3zzzzffe:1900:4545:3:200:f8ff:fe21:67cf'),这显然不是有效的IPv6地址.这里使用正则表达式获得了更好的结果:http://nbviewer.ipython.org/github/rasbt/python_reference/blob/master/tutorials/useful_regex.ipynb (3认同)
  • +1表示正则表达式可以(以与任何源代码相同的方式)实际可读,如果您小心并格式化它们. (3认同)
  • @OwN,不幸的是,78 个字符太长,无法作为此封闭线程的替代答案发布,......我将在后续评论中发布,请仔细拼接:`(fe80:(:[0-9a-fA -F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|([0-9a-fA-F]{1,4}:){1,2 }(:[0-9a-fA-F]{1,4}){1,5}|([0-9a-fA-F]{1,4}:){1,3}(:[0 -9a-fA-F]{1,4}){1,4}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4 }){1,6})|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1 ,3}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|( [0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1, 4}:){1,7}:` (2认同)
  • @OwN - 第 2 部分:`|([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a -fA-F]{1,4}:){1,4}:((25[0-5]|2[0-4][0-9]|1{0,1}[0-9] {0,1}[0-9])\.{3,3})(25[0-5]|2[0-4][0-9]|1{0,1}[0-9] {0,1}[0-9])|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|2[0- 4][0-9]|1{0,1}[0-9]{0,1}[0-9])\.{3,3})(25[0-5]|2[0- 4][0-9]|1{0,1}[0-9]{0,1}[0-9])|:((:[0-9a-fA-F]{1,4}) {1,7}|:))` (2认同)
  • 中间一栏的所有IP地址都是错误的。根据[这个答案](https://serverfault.com/questions/444554/what-does-mean-as-an-ip-address-bracket-colon-colon-bracket),可以使用双冒号来替换连续的零块,如果零的长度大于单个块。 (2认同)
  • 请考虑“[0-9a-fA-F]”与某些语言环境(如土耳其语“ç”)错误匹配。在执行此类正则表达式匹配之前,您必须使用专用字符类名称“[[:xdigit:]]”和“[[:digit:]]”或将语言环境切换为“POSIX”或“C”。 (2认同)

Mic*_*ton 51

以下内容将验证IPv4,IPv6(完整和压缩)以及IPv6v4(完整和压缩)地址:

'/^(?>(?>([a-f0-9]{1,4})(?>:(?1)){7}|(?!(?:.*[a-f0-9](?>:|$)){8,})((?1)(?>:(?1)){0,6})?::(?2)?)|(?>(?>(?1)(?>:(?1)){5}:|(?!(?:.*[a-f0-9]:){6,})(?3)?::(?>((?1)(?>:(?1)){0,4}):)?)?(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])(?>\.(?4)){3}))$/iD'
Run Code Online (Sandbox Code Playgroud)

  • 尽管验证ip-s可以像Frank Krueger所说的那样完成,但这个解决方案实际上是回答这个问题的解决方案(虽然我还没有完全测试过),如果你有很多你需要语法测试的IP-s并且可能在一行文本中匹配,您不能使用IP验证技术. (8认同)
  • JavaScript实现了Perl样式正则表达式的子集,而不是整个PCRE.没有PCRE的一些高级功能,我的正则表达式将无法工作. (3认同)
  • 这给了我C#的例外 (2认同)
  • 失败的测试用例:FE80:0000:0000:0000:0202:B3FF:FE1E:8329 在此日期使用最新版本的 Elixir,它在下面使用 PCRE。 (2认同)

Fac*_*tic 23

来自" IPv6正则表达式 ":

(\A([0-9a-f]{1,4}:){1,1}(:[0-9a-f]{1,4}){1,6}\Z)|
(\A([0-9a-f]{1,4}:){1,2}(:[0-9a-f]{1,4}){1,5}\Z)|
(\A([0-9a-f]{1,4}:){1,3}(:[0-9a-f]{1,4}){1,4}\Z)|
(\A([0-9a-f]{1,4}:){1,4}(:[0-9a-f]{1,4}){1,3}\Z)|
(\A([0-9a-f]{1,4}:){1,5}(:[0-9a-f]{1,4}){1,2}\Z)|
(\A([0-9a-f]{1,4}:){1,6}(:[0-9a-f]{1,4}){1,1}\Z)|
(\A(([0-9a-f]{1,4}:){1,7}|:):\Z)|
(\A:(:[0-9a-f]{1,4}){1,7}\Z)|
(\A((([0-9a-f]{1,4}:){6})(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3})\Z)|
(\A(([0-9a-f]{1,4}:){5}[0-9a-f]{1,4}:(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3})\Z)|
(\A([0-9a-f]{1,4}:){5}:[0-9a-f]{1,4}:(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}\Z)|
(\A([0-9a-f]{1,4}:){1,1}(:[0-9a-f]{1,4}){1,4}:(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}\Z)|
(\A([0-9a-f]{1,4}:){1,2}(:[0-9a-f]{1,4}){1,3}:(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}\Z)|
(\A([0-9a-f]{1,4}:){1,3}(:[0-9a-f]{1,4}){1,2}:(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}\Z)|
(\A([0-9a-f]{1,4}:){1,4}(:[0-9a-f]{1,4}){1,1}:(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}\Z)|
(\A(([0-9a-f]{1,4}:){1,5}|:):(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}\Z)|
(\A:(:[0-9a-f]{1,4}){1,5}:(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}\Z)
Run Code Online (Sandbox Code Playgroud)

  • 像这样的正则表达式应该是"代码味道",也许正则表达式不是最合适的解决方案.(虽然,我猜操作确实要求...) (41认同)
  • @ user712092 - 每个看过代码库的人都有这样的眼神 (10认同)
  • 这对RE来说是完全不必要的嘲弄.生成它的程序不明白它在做什么.人类永远不会这样做.不要被明显的复杂性所迷惑 - RE对许多人来说确实是"黑魔法",但是没有理由把它们放在另一个星球上! (2认同)
  • 这确实是一种代码味道;然而,看完之后您会发现每个正则表达式都相当简洁。问题是 ipv6 的“压缩”创建了不同的模式 - 冒号开头、中间和结尾,此外,如果您使用过双冒号,则不能再次使用它,在总数之上双精度之前和之后的冒号必须相加。Perl 6 *可能*能够解决这个问题,但它远远超出了 PCRE 语法的范围。(PS——我没有算最后嵌入的ipv4,它比ipv6部分长!) (2认同)

Joe*_*and 22

听起来你可能正在使用Python.如果是这样,你可以使用这样的东西:

import socket

def check_ipv6(n):
    try:
        socket.inet_pton(socket.AF_INET6, n)
        return True
    except socket.error:
        return False

print check_ipv6('::1') # True
print check_ipv6('foo') # False
print check_ipv6(5)     # TypeError exception
print check_ipv6(None)  # TypeError exception
Run Code Online (Sandbox Code Playgroud)

我认为您不必将Python编译到Python中inet_pton,如果您socket.AF_INET作为第一个参数传入,它也可以解析IPv4地址.注意:这可能不适用于非Unix系统.

  • 您应该在`except`子句中指定异常类型.否则,`except`将捕获所有内容并可能掩盖不相关的错误.这里的类型应该是`socket.error`. (4认同)
  • Re:其他错误...如果用户传入非字符串,则会导致TypeError被吃掉.很明显,列表不是ipv6,但我可能想让它鲤鱼,我传递的是错误的类型. (2认同)

Roh*_*kar 14

这也会捕获环回(:: 1)和 ipv6 地址。将 {} 更改为 + 并将 : 放在第一个方括号内。

([a-f0-9:]+:+)+[a-f0-9]+
Run Code Online (Sandbox Code Playgroud)

使用 ifconfig -a 输出http://regexr.com/进行测试

Unix 或 Mac OSx 终端 o 选项仅返回匹配的输出(ipv6),包括 ::1

ifconfig -a | egrep -o '([a-f0-9:]+:+)+[a-f0-9]+'
Run Code Online (Sandbox Code Playgroud)

获取所有 IP 地址(IPv4 或 IPv6)并在 unix OSx 术语上打印匹配项

ifconfig -a | egrep -o '([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}) | (([a-f0-9:]+:+)+[a-f0-9]+)'
Run Code Online (Sandbox Code Playgroud)


Jon*_*ram 9

我必须强烈反对Frank Krueger的答案.

虽然您说需要正则表达式来匹配IPv6地址,但我假设您真正需要的是能够检查给定字符串是否是有效的IPv6地址.这里有一个微妙但重要的区别.

有多种方法可以检查给定字符串是否是有效的IPv6地址,而正则表达式匹配只是一种解决方案.

如果可以,请使用现有库.该库将有更少的错误,它的使用将导致更少的代码供您维护.

因子神秘主义者建议的正则表达是漫长而复杂的.它很可能有效,但你也应该考虑如果它出乎意料地失败你将如何应对.我想在这里提出的观点是,如果你不能自己形成一个必需的正则表达式,你将无法轻松调试它.

如果您没有合适的库,那么编写自己的不依赖于正则表达式的IPv6验证例程可能会更好.如果您编写它,您就会理解它,如果您理解它,您可以添加注释来解释它,以便其他人也可以理解并随后维护它.

使用正则表达式时要谨慎行事,其功能无法向其他人解释.

  • 当他几乎肯定在大块文本中搜索IP时,你假设他正在验证单个IP. (4认同)

Rem*_*rin 8

我不是Ipv6专家,但我认为你可以用这个更轻松地获得一个非常好的结果:

^([0-9A-Fa-f]{0,4}:){2,7}([0-9A-Fa-f]{1,4}$|((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.|$)){4})$
Run Code Online (Sandbox Code Playgroud)

回答"是一个有效的ipv6"它对我来说似乎没问题.把它分解成几部分......忘掉它吧.我省略了未指定的一个(::),因为我的数据库中没有"未指定的地址".

开头: ^([0-9A-Fa-f]{0,4}:){2,7}< - 匹配可压缩部分,我们可以将其翻译为:2到7之间的冒号,它们之间可能有heaxadecimal数.

接下来是: [0-9A-Fa-f]{1,4}$< - 一个十六进制数字(省略前导0)或 ((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.|$)){4}< - 一个Ipv4地址

  • 这与“::1”不匹配 (2认同)

小智 7

此正则表达式将根据使用REGULAR EXTENDED模式的正则表达式的GNU C++实现匹配有效的IPv6和IPv4地址:

"^\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][0-9]|1[0-9][0-9]|[1-9]?[0-9])(\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])(\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])){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][0-9]|1[0-9][0-9]|[1-9]?[0-9])(\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])){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][0-9]|1[0-9][0-9]|[1-9]?[0-9])(\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])){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][0-9]|1[0-9][0-9]|[1-9]?[0-9])(\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])){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][0-9]|1[0-9][0-9]|[1-9]?[0-9])(\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])(\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])){3}))|:)))(%.+)?\s*$"
Run Code Online (Sandbox Code Playgroud)


Bra*_*ert 5

如果你使用 Perl 试试Net::IPv6Addr

use Net::IPv6Addr;

if( defined Net::IPv6Addr::is_ipv6($ip_address) ){
  print "Looks like an ipv6 address\n";
}
Run Code Online (Sandbox Code Playgroud)

网络地址::IP

use NetAddr::IP;

my $obj = NetAddr::IP->new6($ip_address);
Run Code Online (Sandbox Code Playgroud)

验证::IP

use Validate::IP qw'is_ipv6';

if( is_ipv6($ip_address) ){
  print "Looks like an ipv6 address\n";
}
Run Code Online (Sandbox Code Playgroud)


小智 5

谨防!在Java中使用InetAddress及相关类(Inet4Address、Inet6Address、URL)可能会涉及到网络流量!例如 DNS 解析(URL.equals,字符串中的 InetAddress!)。此调用可能需要很长时间并且正在阻塞!

对于 IPv6,我有类似的东西。这当然不会处理 IPv6 的非常微妙的细节,例如仅在某些类别的 IPv6 地址上允许区域索引。而且这个正则表达式不是为组捕获而编写的,它只是一种“匹配”类型的正则表达式。

S - IPv6 段 = [0-9a-f]{1,4}

I - IPv4 = (?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9]{1,2})\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9]{1,2})

示意图(第一部分匹配带有 IPv4 后缀的 IPv6 地址,第二部分匹配 IPv6 地址,最后部分匹配区域索引):

(
(
::(S:){0,5}|
S::(S:){0,4}|
(S:){2}:(S:){0,3}|
(S:){3}:(S:){0,2}|
(S:){4}:(S:)?|
(S:){5}:|
(S:){6}
)
I

|

:(:|(:S){1,7})|
S:(:|(:S){1,6})|
(S:){2}(:|(:S){1,5})|
(S:){3}(:|(:S){1,4})|
(S:){4}(:|(:S){1,3})|
(S:){5}(:|(:S){1,2})|
(S:){6}(:|(:S))|
(S:){7}:|
(S:){7}S
)

(?:%[0-9a-z]+)?
Run Code Online (Sandbox Code Playgroud)

在这里可能的正则表达式(不区分大小写,用需要的东西包围,比如行首/行尾等):

(?:
(?:
::(?:[0-9a-f]{1,4}:){0,5}|
[0-9a-f]{1,4}::(?:[0-9a-f]{1,4}:){0,4}|
(?:[0-9a-f]{1,4}:){2}:(?:[0-9a-f]{1,4}:){0,3}|
(?:[0-9a-f]{1,4}:){3}:(?:[0-9a-f]{1,4}:){0,2}|
(?:[0-9a-f]{1,4}:){4}:(?:[0-9a-f]{1,4}:)?|
(?:[0-9a-f]{1,4}:){5}:|
(?:[0-9a-f]{1,4}:){6}
)
(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9]{1,2})\.){3}
(?:25[0-5]|2[0-4][0-9]|[01]?[0-9]{1,2})|

:(?::|(?::[0-9a-f]{1,4}){1,7})|
[0-9a-f]{1,4}:(?::|(?::[0-9a-f]{1,4}){1,6})|
(?:[0-9a-f]{1,4}:){2}(?::|(?::[0-9a-f]{1,4}){1,5})|
(?:[0-9a-f]{1,4}:){3}(?::|(?::[0-9a-f]{1,4}){1,4})|
(?:[0-9a-f]{1,4}:){4}(?::|(?::[0-9a-f]{1,4}){1,3})|
(?:[0-9a-f]{1,4}:){5}(?::|(?::[0-9a-f]{1,4}){1,2})|
(?:[0-9a-f]{1,4}:){6}(?::|(?::[0-9a-f]{1,4}))|
(?:[0-9a-f]{1,4}:){7}:|
(?:[0-9a-f]{1,4}:){7}[0-9a-f]{1,4}
)

(?:%[0-9a-z]+)?
Run Code Online (Sandbox Code Playgroud)


小智 5

以下正则表达式仅适用于 IPv6。第 1 组与 IP 匹配。

(([0-9a-fA-F]{0,4}:){1,7}[0-9a-fA-F]{0,4})
Run Code Online (Sandbox Code Playgroud)

  • 这与以下内容不匹配:fe80::1 或 2342:32fd::2d32 (7认同)