
本文介绍如何使用正则表达式精准识别并批量删除当前目录下所有文件名纯为数字、且无文件扩展名的临时文件,适用于数据库文档缓存等场景,兼顾安全性与可维护性。
本文介绍如何使用正则表达式精准识别并批量删除当前目录下所有文件名纯为数字、且无文件扩展名的临时文件,适用于数据库文档缓存等场景,兼顾安全性与可维护性。
在基于文件 ID 缓存二进制文档(如从 MySQL 的 BLOB 字段还原)的应用中,常将文件以纯数字命名(如 12345、67890)且不带扩展名的方式保存到本地(例如 Path.cwd().joinpath(str(docID)))。这类文件虽便于映射数据库主键,但退出程序时需自动清理,避免磁盘残留。直接遍历并删除所有“看起来像数字”的文件存在风险——误删配置文件 1.conf 或日志 2024 等非目标项。因此,精准匹配“完整文件名 = 连续数字 + 无扩展名” 是关键。
✅ 正确匹配逻辑说明
- ✅ 匹配:123、0、999999
- ❌ 不匹配:123.txt(含扩展名)、abc123(含字母)、12 3(含空格)、.123(隐藏文件,以点开头)
推荐使用 pathlib 结合 re 实现清晰、跨平台的清理逻辑:
import re
from pathlib import Path
def cleanup_numeric_files(directory: Path = None) -> int:
"""删除指定目录下所有文件名纯为数字、且无扩展名的文件,返回删除数量"""
if directory is None:
directory = Path.cwd()
# 编译正则:^ 表示开头,\d+ 表示一个及以上数字,$ 表示结尾 → 整个文件名必须仅为数字
numeric_pattern = re.compile(r'^\d+$')
deleted_count = 0
for item in directory.iterdir():
if item.is_file() and numeric_pattern.match(item.stem):
# 注意:item.stem 是不含扩展名的文件名;item.name 是完整名称(含扩展名)
# 因此用 item.stem 匹配数字,再确保 item.suffix == '' 才真正无扩展名
if not item.suffix: # 关键:排除 .123、123.json 等情况
try:
item.unlink()
deleted_count += 1
print(f"✓ 已删除: {item.name}")
except PermissionError:
print(f"⚠ 权限不足,跳过: {item.name}")
except OSError as e:
print(f"⚠ 删除失败 {item.name}: {e}")
print(f"→ 共清理 {deleted_count} 个纯数字无扩展名文件")
return deleted_count
# 使用示例(建议在程序退出前调用)
if __name__ == "__main__":
cleanup_numeric_files()⚠️ 重要注意事项
- 安全第一:首次使用建议先将 item.unlink() 替换为 print(f"[DRY RUN] 将删除: {item.name}"),确认输出列表无误后再启用真实删除。
- 路径明确性:显式传入 directory 参数(如 Path("/tmp/doc_cache")),避免误操作当前工作目录下的其他数字命名文件。
- 异常健壮性:unlink() 可能因权限、占用或只读属性失败,务必捕获 PermissionError 和 OSError 并记录。
- 区分 stem 与 name:item.stem 是去掉扩展名后的主体名(如 123.txt 的 stem 是 '123'),而 item.name 是完整名称('123.txt')。本场景必须同时满足 numeric_pattern.match(item.stem) 且 item.suffix == '',才能确保是「纯数字 + 无扩展名」。
- Windows 兼容性提示:Windows 下某些数字文件名(如 CON、PRN)为保留名,但纯数字命名不受影响,无需额外处理。
✅ 总结
该方案通过正则精确约束文件名结构、pathlib 安全遍历、双重条件(stem 匹配 + suffix 为空)严格验证,配合异常处理与预检机制,形成一套生产就绪的清理策略。将其封装为函数后,可在 PyInstaller 打包应用的 atexit 钩子或主程序 finally 块中调用,实现优雅退出与资源自清理。










