IronPython:如何从Python表达式中获取名称?

时间:2011-05-02 09:54:35

标签: ironpython

我有一个带有Python表达式的字符串,例如:

"x + y * 2 > z"

如何获取表达式中使用的名称列表?在上面的例子中,列表是:

x, y, z

在Python中我想我可以使用解析器模块,但是如何在IronPython中执行它,解析器模块似乎不可用?

3 个答案:

答案 0 :(得分:2)

此页面可能会对您有所帮助:http://www.ironpython.info/index.php/The_IronPython_2_Parser

它有一个例子,使用底层的IronPython编译器从python表达式创建一个AST,然后打印那里找到的对象的名称。

我继续将它应用到您的问题中。我在这里使用IronPython 2.0.1,以防您使用的是更新的版本并且他们改变了一些内容......

# run this with IronPython 2
import clr
clr.AddReference('IronPython')
clr.AddReference('Microsoft.Scripting')

from IronPython.Hosting import Python
from IronPython.Compiler import Parser
from IronPython.Compiler.Ast import PythonWalker
from IronPython.Compiler.Ast import NameExpression
from Microsoft.Scripting import ErrorSink
from Microsoft.Scripting import SymbolTable
from Microsoft.Scripting.Runtime import CompilerContext
from Microsoft.Scripting.Hosting.Providers import HostingHelpers


class ExpressionWalker (PythonWalker):
    def __init__(self):
        self.names = []
    def Walk(self, node):
        if isinstance(node, NameExpression):
            self.names.append(SymbolTable.IdToString(node.Name))
        return True

py = Python.CreateEngine()
src = HostingHelpers.GetSourceUnit(py.CreateScriptSourceFromString('x + y * 2 > z'))
pylc = HostingHelpers.GetLanguageContext(py)
p = Parser.CreateParser(CompilerContext(src, pylc.GetCompilerOptions(), ErrorSink.Default), pylc.Options)
ast = p.ParseFile(True)

walker = ExpressionWalker()
ast.Walk(walker)
print walker.names

这打印出以下内容:

['x', 'y', 'z']

答案 1 :(得分:0)

您可以使用.NET Framework的Regex类:

import clr

clr.AddReference('System')
from System.Text.RegularExpressions import Regex

operation = "x + y * 2 > z"

regex = Regex("[a-zA-Z]+")
matches = regex.Matches("x + y * 2 > z")
result = ""
for m in matches:
    result += m.Value + ","

print result

答案 2 :(得分:0)

print filter(lambda x: x.isalpha(), list("x + y * 2 > z"))

OR

def parse_expression(expression, operations=['+','-','*','/','%','^']):
    output = []
    tmp = None
    for x in expression:
        if x.strip() == '':
            continue
        if tmp is None:
            tmp = [x]
        elif not x in operations:
            tmp.append(x)
        else:
            output.append(''.join(tmp))
            tmp = None
    (tmp is not None and output.append(''.join(tmp)))
    return output

OR

import re
print re.findall(r'(?i)(?:[a-z0-9_]+)', ('test_1+ y__2 * c/_3')