Skip to main content
 首页 » 编程设计

python之使用 python 正则表达式匹配所有可能的 1、2、3 和 4 个单词组

2025年05月04日22bjzhanghao

如何使用 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. 

获胜者是格雷格!但是,zx81 得到了正则表达式解决方案的答案检查。你们都投了赞成票。

请您参考如下方法:

重叠匹配:先行欺骗

用一个正则表达式匹配所有组合是可能的。由于匹配重叠,我们将使用前瞻和可选的捕获组。

这里有两个选项。

选项 1:更短的正则表达式,未排序的输出

(?=((((\b\S+)(?: \S+)?)(?: \S+)?)(?: \S+)?)) 

所有组合都被捕获到各种比赛的第 1、2、3 和 4 组。当我们将所有组放在一个集合中时,会消除一些重复项。在 the regex demo ,请查看右下方 Pane 中的组捕获。

示例代码

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'} 

选项 2:更长的正则表达式,排序输出

(?=\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']