确定正则表达式的最大匹配长度的最简单方法是什么?正则表达式的最大匹配长度
具体来说,我使用Python的re
模块。
E.g.对于foo((bar){2,3}|potato)
它将是12.
显然,使用运算符(如*
和+
)的正则表达式在理论上具有无限的匹配长度;在那些情况下返回一个错误或者是没有问题的。使用(?...)
扩展给正则表达式提供错误也很好。
我也可以得到一个近似的上限,只要它总是大于实际的最大长度,但不是太大得多。
确定正则表达式的最大匹配长度的最简单方法是什么?正则表达式的最大匹配长度
具体来说,我使用Python的re
模块。
E.g.对于foo((bar){2,3}|potato)
它将是12.
显然,使用运算符(如*
和+
)的正则表达式在理论上具有无限的匹配长度;在那些情况下返回一个错误或者是没有问题的。使用(?...)
扩展给正则表达式提供错误也很好。
我也可以得到一个近似的上限,只要它总是大于实际的最大长度,但不是太大得多。
解决了,我想。感谢unutbu指点我sre_parse
!
import sre_parse
def get_regex_max_match_len(regex):
minlen, maxlen = sre_parse.parse(regex).getwidth()
if maxlen >= sre_parse.MAXREPEAT: raise ValueError('unbounded regex')
return maxlen
结果:
>>> get_regex_max_match_len('foo((bar){2,3}|potato)')
12
>>> get_regex_max_match_len('.*')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 3, in get_regex_max_match_len
ValueError: unbounded regex
import invRegex
data='foo(bar{2,3}|potato)'
print(list(invRegex.invert(data)))
# ['foobarr', 'foobarrr', 'foopotato']
print(max(map(len,invRegex.invert(data))))
# 9
另一种替代方法是使用从ipermute
this module。
import inverse_regex
data='foo(bar{2,3}|potato)'
print(list(inverse_regex.ipermute(data)))
# ['foobarr', 'foobarrr', 'foopotato']
print(max(map(len,inverse_regex.ipermute(data))))
# 9
后者在'\ w {1,10}'这样一个简单的表达式上分崩离析。尽管如此,它的确提出了如何正确地做到这一点,使用'sre_parse'模块,并且ipermute代码是一个很好的起点。不过,我不确定sre_parse是否是公共API;它似乎没有记录,所以要小心。 – 2010-10-31 15:08:58
不错,我不知道这件事 – 2010-10-31 16:12:48
这将是困难的。例如,正则表达式:'^(?! a {5,10})。*(?<=(aaaa | aaaaa))$'包含一个'。*',但只会匹配四个'a' “环视”限制。 – 2010-10-31 14:11:21
@Bart:在Python中这不是一个有效的正则表达式。你的后视可变长度。 – SilentGhost 2010-10-31 14:14:32
我已经更新了这个问题,我不需要支持'(?...)'。 – adw 2010-10-31 14:18:51