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

如何筛选指定前缀的.shp文件列表?解决数字前缀匹配歧义

精准匹配1-12开头的.shp文件列表问题解决

问题说明

  • 需求:为以1-12开头且后缀为.shp的文件分别生成独立列表
  • 初始代码报错:AttributeError: 'list' object has no attribute 'endswith'
  • 优化后代码缺陷:匹配前缀“1”时,会错误包含以“10”“11”“12”开头的.shp文件

初始报错代码

from os.path import normpath
import os

path_temp2 = normpath(r'C:\Users\tlind\Dropbox\Documents\Temp\temp2layers\')

merge_list = os.listdir(path_temp2)

for i in range(1,13):
    test = []
    check = str(i)
    res = [idx for idx in merge_list if idx.lower().startswith(check.lower())]
    test.append(res)

    for file in test:
        test2 = []
        if file.endswith('.shp'):
            test2.append(file)
        
        print(test2)

存在匹配缺陷的代码

from os.path import normpath
import os

path_temp2 = normpath(r'C:\Users\tlind\Dropbox\Documents\Temp\temp2layers\')

merge_list = os.listdir(path_temp2)

for i in range(1,13):
    check = str(i)
    name_ext_matches = []
    name_matches = [idx for idx in merge_list if idx.lower().startswith(check.lower())]

    for file in name_matches:
    
        if file.endswith('.shp'):
            name_ext_matches.append(file)
    
    print(name_ext_matches)

解决方案

问题根源

startswith方法会匹配所有以目标字符串开头的内容,比如“1”会匹配“10xxx.shp”这类文件名,无法区分单个数字和多位数前缀。需要精准验证前缀是独立的1-12,而非更长数字的开头。

方案1:正则表达式精准匹配

用正则规则确保前缀是目标数字,且之后的字符不是数字(或直接接.shp后缀):

from os.path import normpath
import os
import re

path_temp2 = normpath(r'C:\Users\tlind\Dropbox\Documents\Temp\temp2layers\')
merge_list = os.listdir(path_temp2)

for i in range(1, 13):
    check = str(i)
    # 正则规则:以check开头,后续要么是非数字字符,要么直接到.shp结尾
    pattern = re.compile(f'^{re.escape(check)}(?:\\D|\\.shp$)', re.IGNORECASE)
    matched_files = []
    
    for file in merge_list:
        if file.endswith('.shp') and pattern.match(file):
            matched_files.append(file)
    
    print(f"前缀{i}对应的.shp文件: {matched_files}")

方案2:拆分文件名验证

提取文件名(不含后缀),检查前缀部分完全等于目标数字,且后续字符非数字:

from os.path import normpath, splitext
import os

path_temp2 = normpath(r'C:\Users\tlind\Dropbox\Documents\Temp\temp2layers\')
merge_list = os.listdir(path_temp2)

for i in range(1, 13):
    check = str(i)
    matched_files = []
    
    for file in merge_list:
        if file.endswith('.shp'):
            filename = splitext(file)[0]
            # 截取和check长度一致的前缀,确认匹配,且剩余部分要么为空要么首字符不是数字
            if len(filename) >= len(check):
                prefix = filename[:len(check)]
                rest = filename[len(check):]
                if prefix == check and (not rest or not rest[0].isdigit()):
                    matched_files.append(file)
    
    print(f"前缀{i}对应的.shp文件: {matched_files}")

初始报错原因

初始代码里test.append(res)将列表res嵌套进test,导致后续循环中file是列表类型,而列表没有endswith方法,因此抛出AttributeError。优化后的代码去掉了不必要的嵌套,解决了报错,但未处理前缀匹配精度问题。

内容的提问来源于stack exchange,提问作者Tobias Bowley

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 10:15:27