当前位置: 首页 > Linux

Python中的fnmatch模块使用

时间:2023-04-07 00:34:37 Linux

fnmatch()函数在简单的字符串方法和强大的正则表达式之间匹配函数。如果在数据处理操作中只需要简单的通配符,这通常是一个比较合理的方案。该模块的主要作用是匹配文件名,匹配模式使用Unixshell风格。源代码很简单:"""文件名与shell模式匹配。fnmatch(FILENAME,PATTERN)根据本地约定进行匹配。fnmatchcase(FILENAME,PATTERN)始终考虑大小写。函数通过将模式转换为正则表达式来运行。它们缓存已编译的正则表达式以提高速度。函数translate(PATTERN)返回对应于PATTERN的正则表达式。(它不编译它。)"""importosimportposixpathimportreimportfunctools__all__=["filter","fnmatch","fnmatchcase","translate"]deffnmatch(name,pat):"""测试FILENAME是否与PATTERN匹配。模式是Unixshell样式:*匹配所有内容?匹配任何单个字符[seq]匹配seq中的任何字符[!seq]匹配任何charnotinseqFILENAME中的初始句点并不特殊。如果操作系统需要,FILENAME和PATTERN都首先进行大小写规范化。如果你不想这样做,请使用fnm表壳(文件名,模式)。"""name=os.path.normcase(name)pat=os.path.normcase(pat)returnfnmatchcase(name,pat)@functools.lru_cache(maxsize=256,typed=True)def_compile_pattern(pat):如果isinstance(pat,bytes):pat_str=str(pat,'ISO-8859-1')res_str=translate(pat_str)res=bytes(res_str,'ISO-8859-1')else:res=translate(pat)返回re.compile(res).matchdeffilter(names,pat):"""返回列表NAMES中匹配PAT的子集。"""result=[]pat=os.path.normcase(pat)match=_compile_pattern(pat)ifos.pathisposixpath:#posix上的normcase是NOP。优化它远离循环。fornameinnames:ifmatch(name):result.append(name)else:fornameinnames:ifmatch(os.path.normcase(name)):result.append(name)returnresultdeffnmatchcase(name,pat):"""测试FILENAME是否匹配s图案,包括外壳。这是fnmatch()的一个版本,它不对其参数进行大小写规范化。"""match=_compile_pattern(pat)returnmatch(name)isnotNodeneftranslate(pat):"""将shellPATTERN转换为正则表达式。无法引用元字符。"""i,n=0,len(pat)res=''whilei=n:res=res+'\\['else:stuff=pat[i:j].replace('\\','\\\\')i=j+1ifstuff[0]=='!':stuff='^'+stuff[1:]elifstuff[0]=='^':stuff='\\'+stuffres='%s[%s]'%(res,stuff)else:res=res+re.escape(c)返回r'(?s:%s)\Z'resfnmatch["filter","fnmatch","fnmatchcase","translate"]中的5个函数filter以列表形式返回结果defgen_find(filepat,top):"""查找目录树下所有匹配Shell正则模式的文件名:paramfilepat:shell正则模式:paramtop:目录路径:return:fileabsolutepathgenerator"""forpath,_,filenamesinos.walk(top):forfileinfnmatch.filter(filenames,filepat):yieldos.path.join(path,file)fnmatch#列出元组中的所有python文件pyfiles=[pyforpyin('restart.py','index.php','file.txt')iffnmatch(py,'*.py')]#字符串的startswith()和endswith()方法对于过滤目录的内容也很有用。fnmatchcase是区分大小写的文件匹配#这两个函数的一个经常被忽视的特性是在处理非文件名的字符串时它们也很有用例如,假设您有一个街道地址列表address=['5412NCLARKST','1060WADDISONST','1039WGRANVILLEAVE','2122NCLARKST','4802NBROADWAY',]print([addrforaddrinaddressiffnmatchcase(addr,'*ST')])translate这个好像很少用到。如前所述,fnmatch是一种Unixshell匹配样式。您可以使用translate将其转换为正则表达式。比如A栗子shell_match='Celery_?*.py'print(translate(shell_match))#输出结果:(?s:Celery_..*\.py)\ZCelery_..*\.py就是正则的写法表达式。搜索并关注微信公众号:ID:bbcoins