You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 08:25:46