非贪婪正则表达式根据正则表达式中原子的位置表现出贪婪行为

3

我遇到了一个情况,我想在正则表达式模式中使用非贪婪原子.*?

set input "Device ID: HOST1
Interface: GigabitEthernet0/1,  Port ID (outgoing port): GigabitEthernet2/43
Device ID: HOST2
Entry address(es):
Interface: GigabitEthernet0/2,  Port ID (outgoing port): GigabitEthernet2/43
"

puts "======== Non-Greedy regex starting with some other patterns ========"
puts [ regexp -inline {Device\s+ID:.*?outgoing\s+port\):\s+} $input]
puts "======== Non-Greedy regex at first ========"
puts [ regexp -inline {.*?outgoing\s+port\):\s+} $input]

输出:

======== Non-Greedy regex starting with some other patterns ========
{Device ID: HOST1
Interface: GigabitEthernet0/1,  Port ID (outgoing port): GigabitEthernet2/43
Device ID: HOST2
Entry address(es):
Interface: GigabitEthernet0/2,  Port ID (outgoing port): }
======== Non-Greedy regex at first ========
{Device ID: HOST1
Interface: GigabitEthernet0/1,  Port ID (outgoing port): }

.*?outgoing\s+port\):\s+匹配到第一次出现的时候,模式Device\s+ID:.*?outgoing\s+port\):\s+并没有停止在第一次匹配出现的位置。

为什么非贪婪匹配的行为会受到原子放置的影响?

1个回答

4
这里有关于贪婪/非贪婪偏好的内容,虽然(在我看来)没有很好的文档记录,但是re_syntax手册页面中指出:

一个分支的偏好与其中第一个具有偏好的量词原子相同。

(强调是我的)

所以如果你将.*作为第一个量词,整个正则表达式将是贪婪的,
如果你将.*?作为第一个量词,整个正则表达式将是非贪婪的。


1
哦,太好了,我在回答问题时为了记忆而重新阅读了一遍,但并没有发现 Device\s+... 中的第一个操作符是贪婪的。所以如果我理解得没错的话,将第一个 \s+ 改为 \s+? 就可以了? - Tensibai
@Tensibai和@glenn:是的!使用Device\s+?ID:.*?outgoing\s+port\):\s+,它只匹配到第一个出现的位置。这太好了。感谢Glenn先生!!! - Dinesh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接