尝试学习正则表达式子例程。我制作了这个正则表达式来匹配 IP 地址。它可以在记事本++中工作,但是当我在网上的PCRE测试器中尝试它时,它只匹配最后一组中最多2位数字的IP。你能帮我理解为什么吗?
b((d{1,2}|[01]d{2}|2[0-4]d|25[0-5]).){3}(?2)b
在NPP中的示例" 192.168.0.219 192.168.0.21 "中,我有2个匹配项,而PCRE(regex101.com(仅匹配第二个地址。
记事本++使用正则表达式的boost。请参阅此处: Notepad++ 使用哪个正则表达式引擎?.所以这也许可以解释其中的区别。
问题是这块d{1,2}
,它不会像您期望的那样使用递归(在 PCRE 上(。在非递归情况下,您被迫在数字后找到一个点。
但是由于递归针对第2组,你"进入"递归模式,你找到d{1,2}
(21
来自219
(并结束递归。然后,当退出时,你应该找到b
,但你没有(你找到一个9
(,所以你失败了。
也许 boost 引擎在进入递归之前会考虑整个表达式。或者,它可能有一个不同的回溯系统,允许回溯递归并再次重新评估递归,以用于其他一些选项组。最后,不同的实现会导致不同的结果。
要使两个 thig 工作相同,您可以使用以下内容:
b(([01]d{2}|2[0-4]d|25[0-5]|d{1,2}).){3}(?2)b
也就是说,您将d{1,2}
作为最后一个选项。
演示
通常,对选项组进行排序是一种很好的做法(例如,假设(aaa|aa|a)
(,以便首先出现最长的模式(如果可能出现一些重叠(
作为替代方法,如果您想在组中保持相同的顺序,您可以使用:
b((d{1,2}(?!d)|[01]d{2}|2[0-4]d|25[0-5]).){3}(?2)b
(我们在后面加了一个负面的看d{1,2}
之后一定没有数字(