使用regex排除引号中的大小写



我有一段代码,它从一个单独的文件中检索字典的变量名。代码:

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

这正确地将ad识别为字典,同时避免了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 = {']

最新更新