如何使用python正则表达式匹配字符串中1,2,3和4个单词的所有可能序列?所有序列必须仅包含相邻的单词。所以:
str1 = 'AA BB CC DD EE FF GG HH'
matches = re.findall(r'insert ninja regex here', str1)
for match in matches:
print match
应输出:
AA
AA BB
BB
AA BB CC
BB CC
CC
AA BB CC DD
BB CC DD
CC DD
DD
BB CC DD EE
CC DD EE
DD EE
EE
... etc etc
由于
有四个正则表达式的可能解决方案(如果您有更高效,更快捷的方法,请告诉我):
matches4 = re.findall(r'(?=((?:\s\S+){3}\s\S+))', str1)
matches3 = re.findall(r'(?=((?:\s\S+){2}\s\S+))', str1)
matches2 = re.findall(r'(?=((?:\s\S+){1}\s\S+))', str1)
matches1 = re.findall(r'(?=(\s\S+))', str1)
结果如下:
I ran all 4 answers on a string with 138.2k characters and 22.2k words:
my answer=0.0856201648712s.
zx81 answer option 1=0.0598151683807s.
zx81 answer option 2=0.0905468463898s.
Greg Hewgill answer=0.0292818546295s.
获胜者是GREG!但是,zx81可以获得正则表达式解决方案的答案。你们都投票了。
答案 0 :(得分:4)
您可以在不使用任何正则表达式的情况下执行此操作,并且这样做可能更容易。
>>> str1 = 'AA BB CC DD EE FF GG HH'
>>> a = str1.split()
>>> [" ".join(a[i:i+n]) for n in range(1, 5) for i in range(len(a)-n+1)]
['AA', 'BB', 'CC', 'DD', 'EE', 'FF', 'GG', 'HH', 'AA BB', 'BB CC', 'CC DD', 'DD EE', 'EE FF', 'FF GG', 'GG HH', 'AA BB CC', 'BB CC DD', 'CC DD EE', 'DD EE FF', 'EE FF GG', 'FF GG HH', 'AA BB CC DD', 'BB CC DD EE', 'CC DD EE FF', 'DD EE FF GG', 'EE FF GG HH']
在任何情况下,它都比任何正则表达式更容易阅读。
答案 1 :(得分:4)
可以将所有组合与单个正则表达式匹配。由于匹配重叠,我们将使用前瞻和可选的捕获组。
以下是两个选项。
(?=((((\b\S+)(?: \S+)?)(?: \S+)?)(?: \S+)?))
所有组合都被捕获到各种比赛的第1,2,3和4组。当我们将所有小组组合成一组时,会消除一些欺骗。在the regex demo中,请查看右下方窗格中的群组捕获。
示例代码
import re
subject = "AA BB CC DD EE FF GG HH"
reobj = re.compile(r"(?=((((\b\S+)(?: \S+)?)(?: \S+)?)(?: \S+)?))")
result = reobj.findall(subject)
tokens = set()
for a in result:
for b in a:
tokens.add(b)
print(tokens)
<强>输出强>
{'CC DD EE', 'EE FF GG HH', 'GG', 'DD EE FF',
'FF', 'DD EE FF GG', 'BB CC DD', 'DD EE', 'FF GG',
'CC', 'FF GG HH', 'HH', 'EE FF GG', 'AA BB', 'CC DD',
'AA BB CC', 'DD', 'GG HH', 'AA', 'BB CC DD EE',
'EE FF', 'EE', 'AA BB CC DD', 'BB', 'BB CC',
'CC DD EE FF'}
(?=\b(\S+(?: \S+){3}))?(?=\b(\S+(?: \S+){2}))?(?=\b(\S+ \S+))?(?=(\b\S+))
当我们构建列表时,需要删除一些空字符串。
示例代码
import re
subject = "AA BB CC DD EE FF GG HH"
reobj = re.compile(r"(?=(\b\S+))(?=\b(\S+ \S+))?(?=\b(\S+(?: \S+){2}))?(?=\b(\S+(?: \S+){3}))?")
result = reobj.findall(subject)
tokens = []
for a in result:
for b in a:
if b != "":
tokens.append(b)
print(tokens)
<强>输出强>
['AA', 'AA BB', 'AA BB CC', 'AA BB CC DD',
'BB', 'BB CC', 'BB CC DD', 'BB CC DD EE',
'CC', 'CC DD', 'CC DD EE', 'CC DD EE FF',
'DD', 'DD EE', 'DD EE FF', 'DD EE FF GG',
'EE', 'EE FF', 'EE FF GG', 'EE FF GG HH',
'FF', 'FF GG', 'FF GG HH',
'GG', 'GG HH',
'HH']
答案 2 :(得分:0)
效率很高 - 有四个正则表达式的解决方案(如果你有更高效,更快捷的方法,请告诉我):
matches4 = re.findall(r'(?=((?:\s\S+){3}\s\S+))', str1)
matches3 = re.findall(r'(?=((?:\s\S+){2}\s\S+))', str1)
matches2 = re.findall(r'(?=((?:\s\S+){1}\s\S+))', str1)
matches1 = re.findall(r'(?=(\s\S+))', str1)