我正在尝试找出一个匹配文件路径字符串的正则表达式模式,其中名为“cmd.exe”的文件不在“System32”文件夹或其任何子文件夹中。
模式应与此匹配:
C:\Tools\calc.exe
但不是这个:
C:\Windows\System32\calc.exe
C:\Windows\System32\De-de\calc.exe
我尝试了背后的负面看法:
(?<![Ss]ystem32)\\calc\.exe
(?<![Ss]ystem32).*\\calc\.exe
(?<![Ss]ystem32[.*])\\calc\.exe
但到目前为止没有任何效果。 有人看到我的错误吗?
您可以在此处查看我的示例并自行尝试: http://rubular.com/r/syAoEn7xxx
感谢您的帮助。
答案 0 :(得分:5)
要回答问题的正则表达式问题,问题是re
不支持可变长度的外观:
rx = r'(?<!System32.*)calc.exe'
re.search(rx, r'C:\Tools\calc.exe')
> sre_constants.error: look-behind requires fixed-width pattern
有两种解决方法:
安装并使用支持该功能的更新regex模块(以及更多功能):
rx = r'(?<!System32.*)calc.exe'
print regex.search(rx, r'C:\Tools\calc.exe') # <_regex.Match object at 0x1028dd238>
print regex.search(rx, r'C:\Windows\System32\calc.exe') # None
或重新表达表达式,使其不需要变量lookbehind:
rx = r'^(?!.*System32).*calc.exe'
print re.search(rx, r'C:\Tools\calc.exe') # <_sre.SRE_Match object at 0x10aede238>
print re.search(rx, r'C:\Windows\System32\calc.exe') # None
答案 1 :(得分:1)
在使用文件名时,您应该使用os.path
- 模块中的函数。
我建议:
from os.path import basename, dirname
paths = [r"C:\Tools\calc.exe",
r"C:\Windows\System32\calc.exe",
r"C:\Windows\System32\De-de\calc.exe"]
good_paths = [p for p in paths if basename(p).lower() == "calc.exe"
and not "system32" in dirname(p).lower()]
核心是对paths
的列表理解,检查basename
(路径的最后部分)和dirname
,包含目录的名称。
答案 2 :(得分:0)
你可以在没有正则表达式的情况下完成。
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))
答案 3 :(得分:0)
这里不需要后视镜,更不用说宽度可变的了。改为使用预测:
(?i)^(?:(?!\\System32\\).)*\\calc\.exe$
这将匹配所需的\system32\
字符串之前不包含不区分大小写的字符串\calc.exe
的任何内容。表达式的(?i)
部分使其右侧不区分大小写(如果这是针对Windows文件系统的话,这可能是一个不错的选择)。
我很乐意推荐regular-expressions.info。它是在许多怪癖和风味中学习正则表达式的绝佳资源。