正则表达式子例程在 NPP 中工作,但在 PCRE 中行为奇怪



尝试学习正则表达式子例程。我制作了这个正则表达式来匹配 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}之后一定没有数字(

相关内容

  • 没有找到相关文章

最新更新