Skip to main content
 首页 » 编程设计

python之遍历文件从列表中查找单词时的 findall() 正则表达式

2025年05月04日26dflying

我的代码可以递归地遍历文件,从列表中查找单词。如果找到,则打印出找到它的文件、搜索的字符串以及找到它的行。

我的问题是,当搜索 api 时也匹配 myapistring,'pass' 匹配 'compass','dev' 匹配 'device' 而不是实际的词.所以我需要在某处实现正则表达式,但我不确定 for 循环的位置和部分。

我(认为)有效的正则表达式是:

regex='([\w.]+)' 
 
rootpath=myDir 
wordlist=["api","pass","dev"] 
exclude=["testfolder","testfolder2"] 
complist=[] 
 
for word in wordlist: 
        complist.extend([re.compile(word)]) 
 
    for path,name,fname in os.walk(rootpath): 
        name[:] = [d for d in name if d not in exclude] 
        for fileNum in fname: 
            i=path+"/"+fileNum 
            files.append(i) 
 
    for fileLine in files: 
        if any(ext in fileLine for ext in exten):     
            count=0  
            for line in open(fileLine, "r").readlines(): 
                count=count+1 
                for lv in complist: 
                    match = lv.findall(line, re.IGNORECASE) 
 
                    for mat in match:  
                        [print output] 

谢谢

编辑: 添加了提供的代码:

for word in wordlist: 
        complist.extend([re.compile('\b' + re.escape(word) + '\b')]) 

虽然有一些错误,但足够好,我可以使用。

请您参考如下方法:

代替:

for word in wordlist: 
    complist.extend([re.compile(word)]) 

使用word boundaries :

for word in wordlist: 
    complist.extend([re.compile(r'\b{}\b'.format(word))]) 

\b 是单词开头或结尾的零长度匹配,因此 \bthe\b 将匹配此行:

the lazy dog 

但不是这一行:

then I checked StackOverflow 

我想指出的另一件事是,如果 word 包含任何对正则表达式引擎有意义的特殊字符,它们将被解释为正则表达式的一部分。所以,而不是:

complist.extend([re.compile(r'\b{}\b'.format(word))]) 

使用:

complist.extend([re.compile(r'\b{}\b'.format(re.escape(word)))]) 

编辑:如评论中所述,您还希望匹配由 _ 分隔的单词。 _ 被 Python 视为“单词字符”,因此,要将其作为单词分隔符,您可以这样做:

re.compile(r'(?:\b|_){}(?:\b|_)'.format(re.escape(word))) 

在这里查看这项工作:

In [45]: regex = re.compile(r'(?:\b|_){}(?:\b|_)'.format(re.escape(word))) 
 
In [46]: regex.search('this line contains is_admin') 
Out[46]: <_sre.SRE_Match at 0x105bca3d8> 
 
In [47]: regex.search('this line contains admin') 
Out[47]: <_sre.SRE_Match at 0x105bca4a8> 
 
In [48]: regex.search("does not have the word") 
 
In [49]: regex.search("does not have the wordadminword")