【问题标题】:Python 3 filtering directories by name that matches specific patternPython 3 按名称过滤与特定模式匹配的目录
【发布时间】:2015-09-02 07:30:40
【问题描述】:

目前我正在开发将执行特定目录清理的脚本。

例如: 目录:/app/test/log 包含许多具有名称模式 testYYYYMMDD 和 logYYYYMMDD 的子目录

我需要的是只过滤掉像 testYYYYMMDD 这样的目录

要获取给定目录中具有绝对路径的所有文件夹,我使用:

folders_in_given_folder = [name for name in os.listdir(Directory) if os.path.isdir(os.path.join(Directory, name))]
folder_list = []
for folder in folders_in_given_folder:
    folder_list.append([os.path.join(Directory, folder)])
print(folder_list)

给出输出:

[['/app/test/log/test20150615'], ['/app/test/log/test20150616'], ['/app/test/log/b'], ['/app/test/log/a'], ['/app/test/log/New folder'], ['/app/test/log/rem'], ['/app/test/log/test']]

所以现在我需要过滤掉符合模式的子目录, 模式可以是:*test*, test*, test2015*

我尝试过使用 glob.glob(),但这似乎只适用于文件而不是目录。

有人可以这么好心地解释一下我如何才能达到预期的结果吗?

【问题讨论】:

    标签: python regex python-3.x directory filtering


    【解决方案1】:
    import os 
    import re
    
    result = []
    reg_compile = re.compile("test\d{8}")
    for dirpath, dirnames, filenames in os.walk(myrootdir):
        result = result + [dirname for dirname in dirnames if  reg_compile.match(dirname)]
    

    根据建议,我会解释(感谢 -1 btw :D)

    compile("test\d{8}) 将准备一个正则表达式,匹配任何名为 test 的文件夹,后跟 8 位数字格式的日期。

    然后我利用os.walk 方法将每个文件夹正确地放在folders 迭代器中(从而避免使用is_dir 方法)

    使用[dirname for dirname in dirnames if reg_compile.match(dirname)] 行过滤名称与上述正则表达式匹配的文件夹。

    对于第一个有效的答案(是的,这是第一个)(在我的计算机上针对 python2 和 python3 进行了测试),我觉得被否决是很苛刻的。接受的答案也包含我使用的相同类型的正则表达式。现在我也同意我应该早点解释。

    请您删除该反对票吗?

    【讨论】:

    • 请尝试解释您所做的事情,而不是仅仅粘贴代码 sn-ps 作为答案 - 这样,OP(和其他任何人)将能够更好地理解。
    【解决方案2】:

    你需要使用 re 模块。 re 模块是正则表达式 python 模块。 re.compile创建re对象,可以使用match方法过滤列表。

        import re
        R = re.compile(pattern)
        filtered = [folder for folder in folder_list if R.match(folder)]
    

    作为一种模式,你可以像这样使用 smth:

    >>> R = re.compile(".*test.*")
    >>>
    >>> R.match("1test")
    <_sre.SRE_Match object at 0x024ED800>
    >>> R.match("1test")
    <_sre.SRE_Match object at 0x024ED598>
    >>> R.match("test2015")
    <_sre.SRE_Match object at 0x024ED800>
    >>> R.match("1test2")
    <_sre.SRE_Match object at 0x024ED598>
    

    【讨论】:

      【解决方案3】:
      Python 3.4.2 (default, Oct  8 2014, 13:08:17) 
      >>> import re
      >>> re.match(r'.*/[^/]*test[^/]*$', '/app/test/log/test20150616')
      <_sre.SRE_Match object; span=(0, 26), match='/app/test/log/test20150616'>
      >>> 
      

      正则表达式r'.*/[^/]*test[^/]*$' 表示匹配任何以/*test* 结尾的路径,其中* 匹配除/ 之外的任何路径。

      【讨论】:

        猜你喜欢
        • 2018-08-12
        • 1970-01-01
        • 1970-01-01
        • 2019-06-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-10-05
        • 2021-08-03
        相关资源
        最近更新 更多