正则表达式和 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 ...
我是 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 ...