我试图找出一个匹配文件路径字符串的regex模式,其中一个名为"cmd.exe"的文件不位于"System32"文件夹或它的任何子文件夹中。
Pattern应该匹配:
C:Toolscalc.exe
但不在此:
C:WindowsSystem32calc.exe
C:WindowsSystem32De-decalc.exe
我试着消极地看后面:
(?<![Ss]ystem32)\calc.exe
(?<![Ss]ystem32).*\calc.exe
(?<![Ss]ystem32[.*])\calc.exe
但是到目前为止都没有效果。有人看到我的错误了吗?
你可以看到我的例子,并尝试自己在这里:http://rubular.com/r/syAoEn7xxx
谢谢你的帮助。
要回答这个问题的正则表达式方面,问题是re
不支持可变长度的回溯:
rx = r'(?<!System32.*)calc.exe'
re.search(rx, r'C:Toolscalc.exe')
> sre_constants.error: look-behind requires fixed-width pattern
有两种解决方法:
安装并使用更新的regex模块,它支持这个功能(以及更多):
rx = r'(?<!System32.*)calc.exe'
print regex.search(rx, r'C:Toolscalc.exe') # <_regex.Match object at 0x1028dd238>
print regex.search(rx, r'C:WindowsSystem32calc.exe') # None
或重新表达表达式,使其不需要变量后看:
rx = r'^(?!.*System32).*calc.exe'
print re.search(rx, r'C:Toolscalc.exe') # <_sre.SRE_Match object at 0x10aede238>
print re.search(rx, r'C:WindowsSystem32calc.exe') # None
在处理文件名时应该使用os.path
-module中的函数。
我提出:
from os.path import basename, dirname
paths = [r"C:Toolscalc.exe",
r"C:WindowsSystem32calc.exe",
r"C:WindowsSystem32De-decalc.exe"]
good_paths = [p for p in paths if basename(p).lower() == "calc.exe"
and not "system32" in dirname(p).lower()]
核心是paths
的列表推导,检查basename
(路径的最后一部分)和dirname
(包含目录的名称)。
不使用regex也可以。
def iter_good_paths(list_of_paths):
for path in list_of_paths:
parts = path.lower().split(r'')
if parts[-1] == 'calc.exe' and 'System32' in parts:
yield path
,像这样使用
print list(iter_good_paths(list_of_paths))
这里不需要向后看,更不用说可变宽度了。请使用提前查找:
(?i)^(?:(?!\System32\).)*\calc.exe$
这将匹配在所需的calc.exe
字符串之前不包含大小写不敏感字符串system32
的任何内容。表达式的(?i)
部分使得它右边的所有内容不区分大小写(如果这是一个windows文件系统,这可能是一个很好的选择)。
我很乐意推荐正则表达式。info。它是学习正则表达式的许多特性和风格的优秀资源。