我可以让这个(Python)正则表达式更快吗?
我正在尝试编写一个正则表达式,它匹配形式为我可以让这个(Python)正则表达式更快吗?,python,regex,Python,Regex,我正在尝试编写一个正则表达式,它匹配形式为###-##(其中#对应于任何数字)的字符串,但需要注意的是,第二对数字不能是“00”。表达式应该可以与一起使用,并且应该捕获匹配模式的第一次出现 以下是我得到的(有效的): 我对分支或长字符组不感兴趣。有人能推荐一个更好(更清晰,或者更高效)的正则表达式吗 (是的,这是一个微观优化,我注意到了Knuth的正确警告。)使用字符范围可以轻松解决长字符组问题: r"(\d\d-(?:0[1-9]|[1-9]\d))" 但是你不能避开这里的树枝 the_re
###-##
(其中#对应于任何数字)的字符串,但需要注意的是,第二对数字不能是“00”。表达式应该可以与一起使用,并且应该捕获匹配模式的第一次出现
以下是我得到的(有效的):
我对分支或长字符组不感兴趣。有人能推荐一个更好(更清晰,或者更高效)的正则表达式吗
(是的,这是一个微观优化,我注意到了Knuth的正确警告。)使用字符范围可以轻松解决长字符组问题:
r"(\d\d-(?:0[1-9]|[1-9]\d))"
但是你不能避开这里的树枝
the_regex = re.compile("(\d\d-(?:0[1-9]|[1-9]\d))")
l = re.findall(the_regex, '11-01 11-99 10-29 01-99 00-00 11-00')
print l
显示:
['11-01', '11-99', '10-29', '01-99']
如果使用re.finditer,它将返回一个生成器,这可能对您更有利:
it = re.finditer(the_regex, '11-01 11-99 10-29 01-99 00-00 11-00')
print type(it)
print list(i.group(0) for i in it)
这表明:
<type 'callable-iterator'>
['11-01', '11-99', '10-29', '01-99']
['11-01', '11-99', '10-29', '01-99']
还有一种可能性。。。我不确定这是否有效,但似乎。。。。它使用前瞻断言:
r2 = re.compile(r"(\d\d-(?!00)\d\d)")
l = re.findall(r2, 'On 02-14 I went looking for 12-00 and 14-245')
print l
['02-14', '14-24']
然而。。。它似乎没有更快(与上述解决方案相比)。事实上,原来的解决方案在这里是最快的:
# Martijn/Aaron's solution
In [20]: %timeit l = re.findall(the_regex2, '11-01 11-99 10-29 01-99 00-00 11-00')
100000 loops, best of 3: 3.55 µs per loop
# Above version
In [21]: %timeit l = re.findall(r2, '11-01 11-99 10-29 01-99 00-00 11-00')
100000 loops, best of 3: 3.49 µs per loop
#Original post's version.
In [25]: the_regex = re.compile("(\d\d-(?:0[123456789]|[123456789]\d))")
In [26]: %timeit l = re.findall(the_regex, '11-01 11-99 10-29 01-99 00-00 11-00')
100000 loops, best of 3: 3.41 µs per loop
比我快三分钟。或者
重新编译((\d\d-(?:(!00)\d\d))
以将(?:)
保留在OPs中。我认为这不会造成任何伤害,但我认为没有必要。。。原稿就是这样做的,因为|
必须在一个组中,如果不将其标记为非捕获,它将成为一个单独的组。\d\d
在这个例子中不在一个单独的组中,(?!00)
术语已经不被捕获了,所以我认为它实际上没有添加任何内容。在我的测试用例中(我应该展示一些示例数据),这被证明是最快的(无可否认,这是一个相当小的幅度)。当字符串包含以下内容时,是否匹配:123-123
?(您当前的表达式(以及迄今为止的所有答案)不强制任何边界条件,并且将匹配:123-123
中的:23-12
)@ridgerunner良好的点,但在这种情况下,它匹配的字符串保证不具有这种情况。
# Martijn/Aaron's solution
In [20]: %timeit l = re.findall(the_regex2, '11-01 11-99 10-29 01-99 00-00 11-00')
100000 loops, best of 3: 3.55 µs per loop
# Above version
In [21]: %timeit l = re.findall(r2, '11-01 11-99 10-29 01-99 00-00 11-00')
100000 loops, best of 3: 3.49 µs per loop
#Original post's version.
In [25]: the_regex = re.compile("(\d\d-(?:0[123456789]|[123456789]\d))")
In [26]: %timeit l = re.findall(the_regex, '11-01 11-99 10-29 01-99 00-00 11-00')
100000 loops, best of 3: 3.41 µs per loop