目录:
fnmatch
模块简介fnmatch.filter()
函数fnmatch.fnmatch()
函数fnmatch.translate()
函数
fnmatch
模块简介
fnmatch
模块主要用于文件名的匹配,其功能介于简单的字符串匹配和复杂的正则表达式之间。
在日常编程中,我们经常需要处理文件名或目录名的匹配问题,尤其是在进行文件批量操作时。
例如,我们想要找出某个目录下所有的文本文件(.txt
),或者所有以特定前缀开头的图片文件(如 image_*.jpg
)。为了简化这类任务,Python 提供了一个非常实用的模块——fnmatch
。该模块对于文件名的模式匹配,支持类似于 shell 通配符的规则,能够帮助开发者快速筛选出符合条件的文件或目录。
fnmatch.filter()
函数
首先,我们需要导入 fnmatch
模块。接下来,我们将通过几个简单的例子来了解如何使用这个模块的基本功能。
import fnmatch
# 定义一个文件名列表
file_names = [
'report.txt',
'image_01.jpg',
'data.csv',
'image_02.png',
'summary.docx',
'image_03.gif'
]
# 使用 fnmatch.filter() 函数查找所有以 'image_' 开头且扩展名为 .jpg 或 .png 的文件
image_files = fnmatch.filter(file_names, 'image_*.jpg')
image_files.extend(fnmatch.filter(file_names, 'image_*.png'))
# 打印结果
print("找到的图片文件有:", image_files)
# 输出: 找到的图片文件有: ['image_01.jpg', 'image_02.png']
在这个例子中,我们使用了 fnmatch.filter()
函数来筛选文件名。该函数接受两个参数:一个是待筛选的文件名列表,另一个是匹配模式。这里我们分别指定了两种模式 'image_*.jpg'
和 'image_*.png'
,用于匹配所有以 image_
开头并且扩展名为 .jpg
或 .png
的文件。
fnmatch.fnmatch() 函数
fnmatch
模块还提供了 fnmatch.fnmatch()
和 fnmatch.fnmatchcase()
两个函数,它们可以用来判断单个文件名是否符合给定的模式。
fnmatch.fnmatch(filename, pattern): 判断文件名是否与模式匹配,不区分大小写。 fnmatch.fnmatchcase(filename, pattern): 判断文件名是否与模式匹配,区分大小写。
下面的例子展示了这两个函数的使用方法:
import fnmatch
# 测试文件名
test_file = 'Report.TXT'
# 不区分大小写的匹配
if fnmatch.fnmatch(test_file, '*.txt'):
print(f"'{test_file}' 是一个文本文件。")
# 输出: 'Report.TXT' 是一个文本文件。
# 区分大小写的匹配
if not fnmatch.fnmatchcase(test_file, '*.txt'):
print(f"'{test_file}' 不是小写的 .txt 文件。")
# 输出: 'Report.TXT' 不是小写的 .txt 文件。
fnmatch.translate()
函数
fnmatch.translate
函数接受一个 shell 风格的通配符模式作为输入,返回一个对应的正则表达式字符串。这个正则表达式可以直接用于 re
模块中的匹配操作。
import fnmatch
import re
# 定义一个通配符模式
pattern = 'image_*.jpg'
# 将通配符模式转换为正则表达式
regex_pattern = fnmatch.translate(pattern)
# 打印转换后的正则表达式
print("转换后的正则表达式:", regex_pattern)
# 输出: 转换后的正则表达式: (?s:image_.*\.jpg)\Z
# 编译正则表达式
compiled_regex = re.compile(regex_pattern)
# 定义一个文件名列表
file_names = [
'report.txt',
'image_01.jpg',
'data.csv',
'image_02.png',
'summary.docx',
'image_03.gif'
]
# 使用正则表达式匹配文件名
matched_files = [file for file in file_names if compiled_regex.match(file)]
# 打印匹配结果
print("匹配的文件有:", matched_files)
在这个例子中,我们将一个简单的通配符模式 'image_*.jpg'
转换为了正则表达式 '(?s:image_.*\.jpg)\Z'
。可以看到,通配符 *
被转换为了正则表达式中的 .*
,表示任意字符(除换行符外)的任意数量。同时,.
被转义为了 \.
,表示匹配实际的点号字符。
其中:
1、(?s:...)
- 这是一个内联标志(inline flag),它改变了正则表达式的行为。这里的 s
表示启用单行模式(single-line mode),这意味着点号 .
不仅会匹配除了换行符之外的任何字符,还会包括换行符。通常情况下,点号 .
不会匹配换行符。启用单行模式后,整个输入被视为一行,这在处理多行文本时特别有用。
2、\Z
- 这个锚点表示字符串的结束位置。它确保了匹配到的是整个字符串的结尾,而不仅仅是行尾(与 $
锚点不同,后者在多行模式下可以匹配每一行的末尾)。因此,使用 \Z
可以确保 ".jpg" 必须出现在字符串的最末端。
正则表达式 (?s:image_.*\.jpg)\Z
的含义是:从 "image_" 开始,后面跟随任意数量的任意字符(包括换行符),最后以 ".jpg" 结束的字符串。这个表达式常用于匹配那些以 "image_" 开头并以 ".jpg" 结尾的文件名,而且文件名中间可以包含任何字符,包括换行符。