运算符 ?: 在 Ruby 正则表达式中紧跟在 ( 之后,特别是当正则表达式包含组时会做什么?[重复]

问题描述 投票:0回答:1
string = "This is a paragraph with a bunch3c:77:e6:68:66:e9of random MAC addresses 1100:50:7F:E6:96:20hello world 15:00s, 00:50:56:c0:00:08 some other text is written here 00-0C-29-38-1D-61 00:11:22book.FF:DD:CC"
mac_regex = /(?:[0-9A-F]{2}[\:\-]){5}[0-9A-F]{2}/i
mac_addresses = string.scan(mac_regex)
print mac_addresses 

这将返回

["3c:77:e6:68:66:e9", "00:50:7F:E6:96:20", "00:50:56:c0:00:08", "00-0C-29-38-1D-61"]

如果我从

?:
中删除
mac_regex
,那么
mac_regex = /([0-9A-F]{2}[\:\-]){5}[0-9A-F]{2}/i
,那么
print mac_addresses
返回
[["66:"], ["96:"], ["00:"], ["1D-"]]
,这意味着
([0-9A-F]{2}[\:\-]){5}
只匹配第五次出现的八位位组,而不是所有五个都匹配(我的理解是它应该将所有五个匹配在一起)。

为什么

([0-9A-F]{2}[\:\-]){5}
对应于匹配第五个八位位组,而不是一串5个八位位组?为什么需要
?:
([0-9A-F]{2}[\:\-]){5}
->
(?:[0-9A-F]{2}[\:\-]){5}
,使其对应于匹配 5 个八位字节的字符串?

regex ruby
1个回答
0
投票

(?:...)
是非捕获群。使用它是因为 String#scan 有两种不同的行为:

  1. 如果正则表达式没有捕获组,它会输出匹配数组
  2. 如果正则表达式有捕获组,它会输出一个数组数组,其中每个数组都是捕获的组

由于该模式只有一个组,并且它是非捕获的,因此

scan
使用第一个行为并仅以数组形式返回完整的匹配项。

删除

?:
意味着它切换到第二个行为并仅返回该一组。并且由于重复
{5}
是组的 outside,这意味着该组仅指每个八位位组,而不是所有五个八位位组;因此捕获的八位位组将是最后一个匹配的八位位组。

要在没有

?:
的情况下完成相同的行为,您需要为整个模式添加另一个捕获组,然后从结果中提取该组:

mac_regex = /(([0-9A-F]{2}[\:\-]){5}[0-9A-F]{2})/i
mac_addresses = string.scan(mac_regex).map(&:first)
© www.soinside.com 2019 - 2024. All rights reserved.