Python模式负面看后面

时间:2013-03-26 09:45:39

标签: python regex pattern-matching negative-lookbehind

我正在尝试找出一个匹配文件路径字符串的正则表达式模式,其中名为“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

感谢您的帮助。

4 个答案:

答案 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。它是在许多怪癖和风味中学习正则表达式的绝佳资源。