正则表达式和 os.walk

regex and os.walk

我是 python 的新手,但学得很快。我正在尝试将正则表达式与 os.walk 结合使用来忽略我不想处理的目录。我知道您必须就地修改目录而不是创建新列表。我已经尝试了两种方法。我没有收到任何错误,但它仍然遍历所有目录。排除完整的目录名称工作正常。我正在尝试删除名称中带有 'EXP' 或“-”或“3.2”的所有目录。这是一个我想忽略的例子 3.2.2.150-20150424.195805_EXP_manuMain_outOfMemFix

这是我的:

def runtest(filepath_udu: object) -> object:   
    k = 1
    for root, dirs, files in os.walk(filepath_udu, topdown=True):
        dirs[:] = [item for item in dirs 
                   if item not in ('1node','local','remote')]
        dirs[:] = [dir for dir in dirs 
                   if re.search(r'\bEXP\b', dir) not in dirs \
                   or re.search(r'\b3.2\b', dir) not in dirs \
                   or re.search(r'\w+(?:- \w+)+', dir) not in dirs]
    for file in files:
        do something...

我的第二个目录 [:] 被忽略了,我做错了什么?谢谢

它没有被忽略,只是你的条件总是为真,所以你没有过滤掉任何东西。

re.search 将 return 找到匹配对象,否则 None。无论哪种方式,它都不会成为 dirs 的元素,因为 dirs 只是一个字符串列表。所以你所有的测试总是正确的。

不是检查搜索是否在 dirs 中,而是检查它是否为真。 (匹配对象始终为真,None 始终为假。)

此外,在您修复该问题后,我很确定您希望保留 所有 测试失败的值 — 但您使用的是 or而不是 and,这意味着您要保留 any 测试失败的值。

所以:

dirs[:] = [dir for dir in dirs
           if not re.search(r'\bEXP\b', dir)
           and not re.search(r'\b3.2\b', dir) 
           and not re.search(r'\w+(?:-\w+)+', dir)]

或者,如果反过来更容易理解——与其保留所有测试失败的所有值,不如保留所有 none 测试为真的值:

dirs[:] = [dir for dir in dirs if not (
           re.search(r'\bEXP\b', dir) or
           re.search(r'\b3.2\b', dir) or
           re.search(r'\w+(?:-\w+)+', dir))]

不使用 os.walk,您可以在排除符合您的排除条件的子目录后,通过使用 os.scandir 递归遍历您自己的子目录来避免处理列表操作的开销:

def runtest(filepath_udu: object) -> object:
    for entry in os.scandir(filepath_udu):
        if entry.is_dir() and entry.name not in ('1node', 'local', 'remote') and not re.search(r'\bEXP\b', entry.name) and not re.search(r'\b3.2\b', entry.name) and not re.search(r'\w+(?:- \w+)+', entry.name):
            runtest(entry.path)
        else:
            do something ...