我有一段代码,它从一个单独的文件中检索字典的变量名。代码:
import re
f = open('file.py')
f = f.readlines()
for line in f:
line = line.replace('n', '')
a = re.findall(r'(w*) *= *{', line)
a = ''.join(a)
if a != '':
print(a)
我遇到的问题是它返回一组引号内的匹配项。
例如:
"foo = {}" #will output 'foo', but i don't want it to be recognized.
它应该只选取没有引号的字典。但我不确定如何将其添加到正则表达式中。
当前语句适用于所有内容,除了它从引号内的字典中获取:
(w*) *= *{
与其使用正则表达式解析另一个python文件,不如考虑使用ast
模块,它会为您完成实际解释文本的所有繁重工作。有了语法树之后,挑选字典赋值就变得相当简单了。
的例子:
#sample.py
a = {1:2, 3:4}
b = "foo = {4:8, 15:16}"
c = {1,2,3}
def f():
d = {"Hello": "World"}
,
#main.py
import ast
with open("sample.py") as f:
tree = ast.parse(f.read())
for node in ast.walk(tree):
if isinstance(node, ast.Assign) and isinstance(node.value, ast.Dict):
for target in node.targets:
if isinstance(target, ast.Name):
print target.id
结果:a
d
这正确地将a
和d
识别为字典,同时避免了c
(有花括号但不是字典)和foo
(有字典语法,但在字符串中)的棘手情况
如果你的字典总是从一行的开头开始,你可以在regex的开头设置行分隔符(^
),并启用多行。
/^(w+)s*=s*{/gm
或者,您可以使用反向查找,确保您的字典名称位于非引号,非单词字符之后。
/(?<![w"])(w+)s*=s*{/g
其中(?<![w"])
为负向后看。它是一个不匹配的组,确保前面的字符既不是单词字符也不是引号。
您可以尝试以下基于正则表达式的替换。
>>> import re
>>> s = '"foo = {}" bar = {}'
>>> [i for i in re.findall(r'"[^"]*"|(w* *= *{)', s) if i]
['bar = {']