【发布时间】:2015-10-24 06:40:40
【问题描述】:
我需要找到匹配以下模式的输入字符串:
'fe{10,20}.clustera1.example.com'
'fe{10,20}.clustera{1,2}.example.com,fe{1,5}.clusterb{1,8}.example.com'
主机名或主机名中的{} 块可以在输入字符串中重复任意次数。
我首先尝试使用 re 模块进行匹配,在某些情况下需要 10-30 秒。例如,如果在输入字符串的末尾添加一个空格,如下所示:
'fe{10,20}.clustera{1,2}.example.com,fe{1,5}.clusterb{1,8}.example.com '
这需要很长时间才能完成。
import re
string = 'fe{10,20}.clustera{1,2}.example.com,fe{1,5}.clusterb{1,8}.example.com '
print re.match('^([a-z.-]+|{[\d]+(,[\d]+)*})+(,([a-z.-]+|{[\d]+(,[\d]+)*})+)*$', string).group(0)
即使是简化版本(不检查 , 在 {} 块中的正确位置)的行为方式也相同。
print re.match('^([a-z.-]+|{[\d,]+})+(,([a-z.-]+|{[\d,]+})+)*$', string).group(0)
在 Perl 中尝试了相同的正则表达式并使用 Python 正则表达式模块。两者都运行良好且快速。
在这里,两者都不匹配(预期),但运行速度非常快。
echo 'fe{10,20}.clustera{1,2}.example.com,fe{1,5}.clusterb{1,8}.example.com ' | \
perl -nle 'print $_ if /^([a-z.-]+|{[\d]+(,[\d]+)*})+(,([a-z.-]+|{[\d]+(,[\d]+)*})+)*$/'
import regex
string = 'fe{10,20}.clustera{1,2}.example.com,fe{1,5}.clusterb{1,8}.example.com '
print re.match('^([a-z.-]+|{[\d]+(,[\d]+)*})+(,([a-z.-]+|{[\d]+(,[\d]+)*})+)*$', string).group(0)
我使用的正则表达式模式真的有问题吗?是否可以使用 re 模块本身使其工作?
用于测试的 Python 版本是 2.7.6 和 2.7.8
【问题讨论】: