Boost regex忽略“;“最短匹配”;

Boost regex忽略“;“最短匹配”;,regex,boost,Regex,Boost,以下是Python3会话的逐字副本: ~/Documents $ python3 Python 3.5.1 (v3.5.1:37a07cee5969, Dec 5 2015, 21:12:44) [GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> import re &g

以下是Python3会话的逐字副本:

~/Documents $ python3
Python 3.5.1 (v3.5.1:37a07cee5969, Dec  5 2015, 21:12:44) 
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import re
>>> text = 'This (is) a (test)'
>>> print(text)
This (is) a (test)
>>> re.findall('h', text)
['h']
>>> re.findall('\(.+?\)', text)
['(is)', '(test)']
>>> re.findall('\(.+?\)$', text)
['(is) a (test)']
>>> 
我希望最终的
findall
只返回
(test)
,因为它是字符串末尾
\(.+?\)
的最短匹配。相反,它返回
(is)一个(test)
。对于较长的测试字符串,它也会执行相同的操作:

>>> text = 'This (is) (possibly) a (test)'
>>> re.findall('\(.+?\)', text)
['(is)', '(possibly)', '(test)']
>>> re.findall('\(.+?\)$', text)
['(is) (possibly) a (test)']
它与第一次出现的
on)匹配的原因是什么

请注意,我不是在寻找替代的正则表达式。这个问题是关于具体行为的,因为它似乎是错误的


我使用Python只是为了验证;这是Adobe InDesign论坛中的提示,InDesign也使用Boost:

AdobeInDesign提供了同类最佳的页面设计:Indesign及其相关SDK依赖于Boost.Regex、Boost.Functional和其他工具。
((原文如此)

从(on)的第一次出现起,它的匹配原因是什么

因为解析器状态机从左边开始。它就是这样工作的。如果有一个匹配从第一个字符开始,为什么要拒绝它

这应该给你一个线索。你可能想要求中间不要出现括号:
[^(]
而不是

Python 2.7.10 (default, Oct 14 2015, 16:09:02) 
[GCC 5.2.1 20151010] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> text = 'This (is) (possibly) a (test)'
>>> import re
>>> re.findall('\(.+?\)$', text)
['(is) (possibly) a (test)']
>>> re.findall('\([^(]+?\)$', text)
['(test)']
>>> 
从(on)的第一次出现起,它的匹配原因是什么

因为解析器状态机从左边开始。它就是这样工作的。如果有一个匹配从第一个字符开始,为什么要拒绝它

这应该给你一个线索。你可能想要求中间不要出现括号:
[^(]
而不是

Python 2.7.10 (default, Oct 14 2015, 16:09:02) 
[GCC 5.2.1 20151010] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> text = 'This (is) (possibly) a (test)'
>>> import re
>>> re.findall('\(.+?\)$', text)
['(is) (possibly) a (test)']
>>> re.findall('\([^(]+?\)$', text)
['(test)']
>>> 

规则“如果有从第一个字符开始的匹配,为什么要拒绝它…”使用普通的
\(.++\
)应该只匹配第一个
(is)
。当然,还有更多的规则,这一个-贪婪规则是“继续搜索最长的匹配”。因此,完全等效的情况下,人们可能期望“最短匹配”匹配最短的字符串。它是最短的匹配!所有其他较短的匹配都会被拒绝,因为您自己要求它必须在字符串结尾(
$
)处结束。(我想我不需要指出这一点,因为这是与您刚才展示的示例的唯一区别)。因此,它给出了第一个可能的匹配,并且结果是满足标准的最短的一个……我们讨论的是相同的测试结果吗?当然,您不能不同意字符串
(测试)$
比当前的
要短得多,这是一个(测试)$
–为了清晰起见,包含了
$
。“因为解析器状态机从左边开始”将在
这个
–但是它足够聪明,可以跳过它。而且,进一步检查超出绝对要求的最小值也不是问题(如默认贪婪检查规则所示)。跳过“This”不够聪明。它跳过该选项是因为您的模式以一个必需的
)开头。因此,在开始匹配之前,它已经超过
This
,并且在到达
$
(输入结束)之前不会停止,因为这也在你的模式中。好吧,我想我明白了-线索在“.它给出了第一个可能的匹配,结果是满足条件的最短的匹配”。正则表达式从左到右求值,当它匹配
+
时,它使用“向前看”来检查结束标准,即
\)$
在这里,不仅仅是
\)
。它被认为是最短的匹配,因为它实际上是唯一的匹配(它等于贪婪版本的匹配)。规则“如果有从第一个字符开始的匹配,为什么要拒绝它…”使用普通的
\(.+\)
,应该匹配第一个
(is)
仅此而已。当然还有更多的规则,而这一条——贪婪规则是“继续搜索最长匹配”。因此,完全等效的情况下,人们可能期望“最短匹配”匹配最短的字符串。它是最短的匹配!所有其他较短的匹配都会被拒绝,因为您自己要求它必须在字符串结尾(
$
)处结束。(我想我不需要指出这一点,因为这是与您刚才展示的示例的唯一区别)。因此,它给出了第一个可能的匹配,并且结果是满足标准的最短的一个……我们讨论的是相同的测试结果吗?当然,您不能不同意字符串
(测试)$
比当前的
要短得多,这是一个(测试)$
–为了清晰起见,包含了
$
。“因为解析器状态机从左边开始”将在
这个
–但是它足够聪明,可以跳过它。而且,进一步检查超出绝对要求的最小值也不是问题(如默认贪婪检查规则所示)。跳过“This”不够聪明。它跳过该选项是因为您的模式以一个必需的
)开头。因此,在开始匹配之前,它已经超过
This
,并且在到达
$
(输入结束)之前不会停止,因为这也在你的模式中。好吧,我想我明白了-线索在“.它给出了第一个可能的匹配,结果是满足条件的最短的匹配”。正则表达式从左到右求值,当它匹配
+
时,它使用“向前看”来检查结束标准,即
\)$
这里,不仅仅是
\)
。它被认为是最短的匹配,因为它实际上是唯一的匹配(它等于贪婪版本的匹配)。