使用split()与glob.glob()匹配特定格式文件名失败的技术问询
解决多子目录中匹配特定格式文件名的问题
我来帮你搞定这个文件名匹配的难题!你提到用split()和glob.glob()没成功,核心原因是glob的通配符对「可选的run-num段」支持不够灵活,而单纯拆分文件名片段又太繁琐。下面给你两个实用的解决方案:
方案1:优化Glob通配符模式(简单直接)
利用glob的递归匹配和通配符,分别匹配带run-num和不带run-num的文件,再合并结果:
import glob # 匹配带run-num的文件(支持两位数字的run编号,比如run-01到run-99) pattern_with_run = "**/sub-*_ses-*_task-*_run-[0-9][0-9]_info.*" # 匹配不带run-num的文件 pattern_without_run = "**/sub-*_ses-*_task-*_info.*" # 开启recursive=True遍历所有子目录 matched_files = glob.glob(pattern_with_run, recursive=True) + glob.glob(pattern_without_run, recursive=True) # 打印结果 for file_path in matched_files: print(file_path)
说明:
**/表示递归匹配当前目录下的所有子目录[0-9][0-9]精准匹配两位数字的run编号,如果你需要支持一位数(比如run-1),可以改成[0-9]+- 两种模式分别对应你需要的两种文件名格式,合并后就是所有目标文件
方案2:正则表达式+目录遍历(精准可控)
如果你的文件名规则更复杂(比如run-num有范围限制、task-name包含特殊字符),用正则表达式结合os.walk会更灵活:
import os import re # 定义正则表达式,完美匹配两种格式 file_regex = re.compile( r"^sub-\d+_ses-\d+_task-\w+(?:_run-\d{1,2})?_info\..+$" ) target_files = [] # 遍历所有子目录和文件 for root, _, files in os.walk("."): for filename in files: if file_regex.match(filename): target_files.append(os.path.join(root, filename)) # 输出匹配到的文件 for path in target_files: print(path)
正则说明:
^和$确保匹配整个文件名,避免部分匹配sub-\d+匹配sub-后面的任意数字ses-\d+匹配ses-后面的任意数字task-\w+匹配task-后面的字母/数字/下划线(如果task-name有特殊字符,可替换为[^_]+匹配下划线以外的任意字符)(?:_run-\d{1,2})?表示可选的run-num段:?:是不捕获分组,?表示该段可以不存在,\d{1,2}匹配1-2位数字的run编号_info\..+匹配_info.开头的扩展名部分
额外注意点
- 如果需要去重(比如某些文件可能被两种模式同时匹配到),可以把
matched_files转成集合再转回列表:list(set(matched_files)) - 如果你只需要特定扩展名的文件(比如
.nii.gz),可以把通配符或正则里的.*/.+改成.nii.gz
内容的提问来源于stack exchange,提问作者kdestasio
相关产品推荐
相关产品推荐

