fnamtch就是filenamematch, 在python中利用符合linuxshell风格的匹配模块来进行文件名的匹配筛选工作。
fnmatch()函数匹配能力介于简单的字符串方法和强大的正则表达式之间,如果在数据处理操作中只需要简单的通配符就能完成的时候,这通常是一个比较合理的方案。此模块的主要作用是文件名称的匹配,并且匹配的模式使用的Unix shell风格。源码很简单:
\"\"\"Filename matching with shell patterns.
fnmatch(FILENAME, PATTERN) matches according to the local convention.
fnmatchcase(FILENAME, PATTERN) always takes case in account.
The functions operate by translating the pattern into a regular
. They cache the compiled regular s for speed.
The function translate(PATTERN) returns a regular
corresponding to PATTERN. (It does not compile it.)
\"\"\"
import os
import posixpath
import re
import functools
__all__ = [\"filter\", \"fnmatch\", \"fnmatchcase\", \"translate\"]
def fnmatch(name, pat):
\"\"\"Test whether FILENAME matches PATTERN.
Patterns are Unix shell style:
* matches everything
? matches any single character
[seq] matches any character in seq
[!seq] matches any char not in seq
An initial period in FILENAME is not special.
Both FILENAME and PATTERN are first case-normalized
if the operating system requires it.
If you don\'t want this, use fnmatchcase(FILENAME, PATTERN).
\"\"\"
name = os.path.normcase(name)
pat = os.path.normcase(pat)
return fnmatchcase(name, pat)
@functools.lru_cache(maxsize=256, typed=True)
def _compile_pattern(pat):
if 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)
return re.compile(res).match
def filter(names, pat):
\"\"\"Return the subset of the list NAMES that match PAT.\"\"\"
result = []
pat = os.path.normcase(pat)
match = _compile_pattern(pat)
if os.path is posixpath:
# normcase on posix is NOP. Optimize it away from the loop.
for name in names:
if match(name):
result.append(name)
else:
for name in names:
if match(os.path.normcase(name)):
result.append(name)
return result
def fnmatchcase(name, pat):
\"\"\"Test whether FILENAME matches PATTERN, including case.
This is a version of fnmatch() which doesn\'t case-normalize
its arguments.
\"\"\"
match = _compile_pattern(pat)
return match(name) is not None
def translate(pat):
\"\"\"Translate a shell PATTERN to a regular .
There is no way to quote -characters.
\"\"\"
i, n = 0, len(pat)
res = \'\'
while i < n:
c = pat[i]
i = i+1
if c == \'*\':
res = res + \'.*\'
elif c == \'?\':
res = res + \'.\'
elif c == \'[\':
j = i
if j < n and pat[j] == \'!\':
j = j+1
if j < n and pat[j] == \']\':
j = j+1
while j < n and pat[j] != \']\':
j = j+1
if j >= n:
res = res + \'\\\\[\'
else:
stuff = pat[i:j].replace(\'\\\\\',\'\\\\\\\\\')
i = j+1
if stuff[0] == \'!\':
stuff = \'^\' + stuff[1:]
elif stuff[0] == \'^\':
stuff = \'\\\\\' + stuff
res = \'%s[%s]\' % (res, stuff)
else:
res = res + re.escape(c)
return r\'(?s:%s)\\Z\' % res
fnmatch的中的5个函数[\"filter\", \"fnmatch\", \"fnmatchcase\", \"translate\"]
filter 返回列表形式的结果
def gen_find(filepat, top):
\"\"\"
查找符合Shell正则匹配的目录树下的所有文件名
:param filepat: shell正则
:param top: 目录路径
:return: 文件绝对路径生成器
\"\"\"
for path, _, filenames in os.walk(top):
for file in fnmatch.filter(filenames, filepat):
yield os.path.join(path, file)
fnmatch
# 列出元组中所有的python文件 pyfiles = [py for py in (\'restart.py\', \'index.php\', \'file.txt\') if fnmatch(py, \'*.py\')] # 字符串的 startswith() 和 endswith() 方法对于过滤一个目录的内容也是很有用的
fnmatchcase 区分大小写的文件匹配
# 这两个函数通常会被忽略的一个特性是在处理非文件名的字符串时候它们也是很有用的。 比如,假设你有一个街道地址的列表数据 address = [ \'5412 N CLARK ST\', \'1060 W ADDISON ST\', \'1039 W GRANVILLE AVE\', \'2122 N CLARK ST\', \'4802 N BROADWAY\', ] print([addr for addr in address if fnmatchcase(addr, \'* ST\')])
translate 这个似乎很少有人用到,前面说了fnmatch是Unix shell匹配风格,可以使用translate将其转换为正则表达式,举个栗子
shell_match = \'Celery_?*.py\' print(translate(shell_match)) # 输出结果:(?s:Celery_..*\\.py)\\Z
Celery_..*\\.py就是正则表达式的写法。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。
继续阅读与本文标签相同的文章
上一篇 :
投资钛值的你,知道钛链是什么吗?
下一篇 :
python3实现名片管理系统
-
Spring 社区的唯一一个国产开源项目 - Spring Cloud Alibaba 毕业了
2026-05-19栏目: 教程
-
Spring Cloud和Dubbo,孰优孰劣
2026-05-19栏目: 教程
-
Java锁---偏向锁、轻量级锁、自旋锁、重量级锁
2026-05-19栏目: 教程
-
CTF从入门到提升(七)insert 等数据表相关操作注入及例题分享
2026-05-19栏目: 教程
-
合肥新闻联播:“NEXT创新大会”合肥重磅开年 聚焦“新经济”赋能产业升级
2026-05-19栏目: 教程
