2017-01-17 33 views
1

這裏是一個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) a (test)。它同樣爲更長的測試字符串:

>>> text = 'This (is) (possibly) a (test)' 
>>> re.findall('\(.+?\)', text) 
['(is)', '(possibly)', '(test)'] 
>>> re.findall('\(.+?\)$', text) 
['(is) (possibly) a (test)'] 

爲了什麼原因,它與上第一發生(匹配嗎?

請注意,我是而不是尋找替代正則表達式。這個問題是關於具體的行爲,因爲它似乎是錯誤的。


我只用Python來驗證;這是由this question在Adobe公司的InDesign版面提示,和InDesign還採用升壓:

Adob​​e InDesign中提供了一流的頁面設計:InDesign和它的asociated SDK取決於升壓Boost.Regex,Boost.Functional等。
http://www.boost.org/users/uses_shrink.html原文錯別字))

回答

2

,因爲解析器狀態機開始在左邊它從(第一次出現匹配?

什麼原因。這是它的工作原理,如果從第一個字符開始匹配,爲什麼它應該被拒絕?

這應該給你一個線索,你可能想要求沒有削弱ntheses發生在中間:中[^(]代替.

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)'] 
>>> 
+0

規則「如果從第一個字符開始的比賽,爲什麼要拒​​絕。」,使用純​​'\(。+ \)' ,應該只匹配第一個「(是)」。當然,還有更多規則 - 這個貪婪規則是「繼續尋找最長的匹配」。因此,完全相同,人們可能會期望「最短匹配」匹配*最短*可能的字符串。 – usr2564301

+0

這是最短的匹配!所有其他較短的匹配都會被您自己的要求拒絕,它必須在字符串末尾結束('$')。 (我以爲我不需要指出這一點,因爲它實際上是與你之前展示的例子唯一的區別)。所以它給出了第一個可能的匹配,結果是滿足條件的最短匹配。 – sehe

+0

...我們在談論相同的測試結果嗎?當然,你不能不同意字符串'(test)$'比目前的''(是)a(test)$'' - 包含'$'的字符串短。 「因爲解析器狀態機在左邊開始」會在「This」 - 但它足夠聰明,可以跳過*那個*。並且比絕對要求的最小值檢查也不是問題(如缺省貪婪檢查規則所示)。 – usr2564301