在Python中使用不区分大小写的endswith

问题描述 投票:0回答:2

我有一个文件扩展名列表,我必须编写 if 条件。类似的东西

ext = (".dae", ".xml", ".blend", ".bvh", ".3ds", ".ase",
           ".obj", ".ply", ".dxf", ".ifc", ".nff", ".smd",
           ".vta", ".mdl", ".md2", ".md3",
           ".pk3", ".mdc", ".x",
           ".q3o", ".q3s", ".raw",
           ".ac", ".dxf", ".irrmesh",
           ".irr", ".off", ".ter",
           ".mdl", ".hmp", ".mesh.xml",
           ".skeleton.xml", ".material", ".ms3dv",
           ".lwo", ".lws", ".lxo",
           ".csm", ".cob", ".scn",
           ".xgl", ".zgl")
for folder, subfolders, filename in os.walk(directory):
    if any([filename.endswith(tuple(ext)) for filename in filenames]):

我意识到

endswith
区分大小写。例如,我如何将“.xml”和“.XML”视为相同的扩展名?

python regex string os.walk
2个回答
53
投票

只需在调用 lower

 之前调用 
endswith
 将字符串变为小写即可:

ext = (".dae", ".xml", ".blend", ".bvh", ".3ds", ".ase",
           ".obj", ".ply", ".dxf", ".ifc", ".nff", ".smd",
           ".vta", ".mdl", ".md2", ".md3"
           ".pk3", ".mdc", ".x"
           ".q3o", ".q3s", ".raw"
           ".ac", ".dxf", ".irrmesh"
           ".irr", ".off", ".ter"
           ".mdl", ".hmp", ".mesh.xml"
           ".skeleton.xml", ".material", ".ms3dv"
           ".lwo", ".lws", ".lxo"
           ".csm", ".cob", ".scn"
           ".xgl", ".zgl")
for folder, subfolders, filename in os.walk(directory):
    if any([filename.lower().endswith(tuple(ext)) for filename in filenames]):

0
投票

这是一个非常古老的答案,但从 Python 3.3 开始,存在

casefold()
方法,它比
lower()
更激进,并且是更自然的无大小写字符串匹配。所以像下面这样的东西是一个选择:

filename.casefold().endswith(ext)

顺便说一句,

any()
会短路,这意味着它会在第一个 True 处停止,因此如果在生成器表达式而不是列表上调用
any()
,速度会快得多(特别是如果匹配字符串位于开头)一个长列表)因为使用geneexpr,我们可以立即停止
endswith
检查,而使用list,我们必须在
endswith
评估之前对每个字符串执行
any()
检查。

所以而不是

any([filename.lower().endswith(ext) for filename in filenames])
#   ^                                                        ^  <--- list

使用

any(filename.lower().endswith(ext) for filename in filenames)
#  ^                                                        ^   <--- genexpr

最后,由于这个问题被标记为正则表达式,因此这里还有一个正则表达式解决方案。只需编译一个忽略大小写的模式并搜索该模式是否匹配即可。

import re
pat = re.compile(fr"({'|'.join(re.escape(e) for e in ext)})$", re.I)
for folder, subfolders, filenames in os.walk('.'):
    if any(pat.search(filename) for filename in filenames):
        # do something
© www.soinside.com 2019 - 2024. All rights reserved.