如何用正则表达式结合列表推导式匹配路径列表中指定位置含目标数字的完整路径
如何用正则表达式结合列表推导式匹配路径列表中指定位置含目标数字的完整路径
我来帮你解决这个问题!首先咱们先理清楚核心需求:要从路径列表里找出那些文件名中第三个下划线之后、第一个.tif之前的数字恰好等于目标数字的完整路径,而且得避免“找数字1却匹配到10”这种部分匹配的情况。
先分析你原来正则的问题
你之前写的正则没匹配到内容,主要有两个原因:
- 分组
(?:[^\s_/]+_){{3}}的规则太严格了——它要求匹配的内容不能包含下划线,但你的文件名里比如img_ABC_本身就带下划线,自然匹配不上; - 没给目标数字做“精确边界限制”,导致会把包含目标数字的更长数字也算进去,比如找1的时候会匹配10。
正确的正则写法
针对你的路径格式(比如imgs/foldeer/img_ABC_21389_1.tif.tif),我们可以写出精确匹配的正则,结合列表推导式来筛选:
import re # 你的路径列表 list_paths = [ "imgs/foldeer/img_ABC_21389_1.tif.tif", "imgs/foldeer/img_ABC_15431_10.tif.tif", "imgs/foldeer/img_GHC_561321_2.tif.tif", "imgs_foldeer/img_BCL_871125_21.tif.tif" ] # 定义要匹配的目标数字 target_number = 10 # 构建正则模式 pattern = rf".*/img_(?:[^_]*_){{2}}{target_number}\.tif\.tif$" # 用列表推导式筛选匹配的路径 matched_paths = [path for path in list_paths if re.fullmatch(pattern, path)] print(matched_paths) # 输出结果: ["imgs/foldeer/img_ABC_15431_10.tif.tif"]
正则规则拆解
我给你拆解一下这个正则的每个部分,方便你理解和调整:
.*/:匹配路径中最后一个斜杠之前的所有内容(不管目录里有没有下划线都能兼容);img_:锁定文件名的固定开头,确保我们只针对目标格式的文件;(?:[^_]*_){{2}}:这是一个非捕获组,[^_]*匹配任意数量的非下划线字符,后面跟一个下划线,重复2次——刚好覆盖文件名里的前两个下划线部分(比如ABC_和15431_);{target_number}:精确匹配你要找的数字,因为它前面是下划线、后面是.tif的点,所以绝对不会出现“找1匹配10”的部分匹配问题;\.tif\.tif$:匹配文件名的结尾,确保路径严格以.tif.tif结束,避免匹配到无效的后缀。
灵活调整方案
如果你的文件名开头不一定是img_,可以把正则调整成更通用的版本:
pattern = rf".*/(?:[^_]*_){{3}}{target_number}\.tif\.tif$"
这个版本会匹配最后一个斜杠之后、包含三个下划线的文件名,然后是目标数字和.tif.tif结尾,兼容更多文件名开头的情况。
备选思路:不用正则的实现
如果你觉得正则有点绕,也可以用字符串分割的方式实现,可读性更高:
target_number = 1 matched_paths = [] for path in list_paths: # 提取文件名部分 filename = path.split("/")[-1] # 去掉后缀后按下划线分割 parts = filename.replace(".tif.tif", "").split("_") # 判断最后一个分割部分是否等于目标数字 if len(parts) >= 4 and parts[-1] == str(target_number): matched_paths.append(path)
备注:内容来源于stack exchange,提问作者Reut
相关产品推荐
相关产品推荐

