正则表达式 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
使用 lookbehind
和 word boundary
。
(?<!Call\(Name\(')\b\w+\b(?=', Load)
查看演示。
我为此使用了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。
有一个测试字符串:
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)
结果如下:
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
使用 lookbehind
和 word boundary
。
(?<!Call\(Name\(')\b\w+\b(?=', Load)
查看演示。
我为此使用了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。