我已经回过头来寻找可能解决我问题的方法,但我想我今天的google-fu非常糟糕。更不用说我对正则表达式的了解,它接近于零。
我试图仅使用文本处理从一系列Python文件中检索一些“常量”(即模块级全局变量)的定义。基本上,我阅读了Python文件的全文,然后我将正则表达式应用于文本,以找出这些“常量”的位置/内容。
作为一个例子,我可以在我的Python文件中使用以下内容:
CONSTANT_ONE = 0 # standard
CONSTANT_RIGHT = 1 # rotation of 90 on the right
CONSTANT_LEFT = 2 # rotation of 90 on the left
我发现这个正则表达式可以提取变量名称:
re.compile('^(\w+)[ \t]*=', re.M)
然而,这些声明严重失败:
NAME1, NAME2 = 0, None
CONST_1, CONST_2, CONST_3 = range(3)
有什么方法可以修改我的正则表达式以处理这两种情况?如果这是一个非常基本的问题我很抱歉,但我真的不是正则表达式的专家......
提前谢谢。
安德烈。
答案 0 :(得分:3)
我认为使用正则表达式实现这一目标并不容易。可以compile
Python模块,然后向下走AST
来查找变量定义。请参阅http://docs.python.org/library/functions.html#compile和http://docs.python.org/library/ast.html#module-ast上的文档。
编辑:我当前的程序,使用@Sven的想法。
#!/usr/bin/env python
import ast
import sys
# example assignment.
a, b=5, 9
class MyNodeVisitor(ast.NodeVisitor):
"""
Visit nodes in AST. Idea from @Sven.
"""
def visit_Name(self, node):
if isinstance(node.ctx, ast.Store):
print "Assigning name '%s' on line %d" % ( \
node.id, node.lineno)
def visit_FunctionDef(self, node):
pass
def visit_ClassDef(self, node):
pass
def printAssignments(name):
"""
Read Python file and print a list of variable assignments.
"""
# read file.
f=open(name, 'rU')
data=f.readlines()
f.close()
# create AST.
t=ast.parse("".join(data), filename=name, mode='exec')
# find assignments.
MyNodeVisitor().visit(t)
# walk nodes.
# for node in ast.walk(t):
# if isinstance(node, ast.Name) \
# and isinstance(node.ctx, ast.Store) \
# and node.col_offset == 0:
# print "Assigning name '%s' on line %d" % (node.id, node.lineno)
# print all assignments from files.
for name in sys.argv[1:]:
print "=== %s ===" % name
printAssignments(name)
print "====%s====" % ('='*len(name), )
答案 1 :(得分:3)
不要使用正则表达式,而是使用Python的解析器。它更简单:
class TargetExtractor(ast.NodeVisitor):
def visit_Name(self, node):
if isinstance(node.ctx, ast.Store):
print node.id
def visit_FunctionDef(self, node):
pass
def visit_ClassDef(self, node):
pass
TargetExtractor().visit(ast.parse("a, b = 2, 3; c = d"))
打印
a
b
c
您也可以将文件的全部内容传递给ast.parse()
。
答案 2 :(得分:0)
我不知道你这样做的目的是什么,但如果由于某些原因它必须是一个正则表达式(如果不是Svens的回答看起来相当不错+1),这里就是一个:
^([\w\s,]+)=
在此处查看online on Regexr
但这比你想要的更加通用和匹配。