正则表达式 Python 排除一些结果

Regex Python exclude some results

有一个测试字符串:

Module([Assign([Name('a', Store())], Num(2)), Assign([Name('b', Store())], Num(3)), Assign([Name('c', Store())], Str('Hello')), Assign([Name('x', Store())], BinOp(Name('a', Load()), Add(), Name('b', Load()))), Assign([Name('x', Store())], Name('a', Load())), Expr(Call(Name('print', Load()), [Name('a', Load())], [], None, None)), For(Name('i', Store()), Call(Name('range', Load()), [Num(10)], [], None, None), [Expr(Call(Name('print', Load()), [Name('a', Load())], [], None, None))], [])])

我正在尝试从中获取所有加载的变量名。我的正则表达式是

[a-z]+(?=', Load)

结果如下: 如您所见,它还可以找到内置模块,例如 print、range。如何排除它们?要排除的值前面有

Call(Name(' 

我试过了

 (?=Call\(Name\(')[a-z]+(?=', Load)

但没有成功。

我的代码是:

import re

test = '''Module([Assign([Name('a', Store())], Num(2)), Assign([Name('b', Store())], Num(3)), Assign([Name('c', Store())], Str('Hello')), Assign([Name('x', Store())], BinOp(Name('a', Load()), Add(), Name('b', Load()))), Assign([Name('x', Store())], Name('a', Load())), Expr(Call(Name('print', Load()), [Name('a', Load())], [], None, None)), For(Name('i', Store()), Call(Name('range', Load()), [Num(10)], [], None, None), [Expr(Call(Name('print', Load()), [Name('a', Load())], [], None, None))], [])])'''
print(re.findall(r"[a-z]+(?=', Load)", test))
print(re.findall(r"(?=Call\(Name\(')[a-z]+(?=', Load) ", test))

负面回顾:

(?<!Call\(Name\()'(\w+)(?=', Load)

(?<!Call\()Name\('(\w+)', Load

使用 lookbehindword boundary

(?<!Call\(Name\(')\b\w+\b(?=', Load)

查看演示。

https://regex101.com/r/hdxlQ8/1

我为此使用了eval()方法。我不推荐这种方式,但您可以使用它作为替代方案。

这里test是长字符串的变量。 filtered 变量有您想要的值列表。

all = (re.findall(r"[a-z]+(?=', Load)", test))

filtered = []
for each in all:
    try:
        eval(each)
    except NameError:
        filtered.append(each)
    except:
        pass

print filtered

输出:

['a', 'b', 'a', 'a', 'a']

我们尝试使用 eval() 方法执行每个字符串。如果没有任何具有该名称的变量、方法或 class,python 解释器将抛出 NameError 异常,表明这不是方法或变量,因此我们appending/adding 过滤列表中的字符串。

PS。传递 TypeError 等任何其他异常。

这看起来像一个解析树。出于无数原因,我不会为此使用正则表达式,其他人在一些漂亮的 famous posts 中更好地解释了(假设 post 使用 [x]html 但教训仍然存在,不要使用常规表达式来解析更复杂的语法)。

我的理解是 AST,在这种情况下实际的具体解析树使用上下文无关文法,因此不是规则的,不能使用正则表达式可靠地解析。另外,就步行能力而言,该代码已经处于非常方便的状态。如果有的话,重新创建对象并遍历树,同时知道变量名称将在 Assign 语句的左侧终端,其值在右侧的规则。与使用正则表达式相比,这肯定会花费更少的时间并减少麻烦。

帮自己一个忙,不要尝试使用正则表达式,除非你正在处理这些已知的小品种。

对于further reading