如何解析代码(在Python中)?

2024-10-01 15:34:00 发布

您现在位置:Python中文网/ 问答频道 /正文

我需要解析一些特殊的数据结构。它们的格式有点像C,大致如下所示:

Group("GroupName") {
    /* C-Style comment */
    Group("AnotherGroupName") {
        Entry("some","variables",0,3.141);
        Entry("other","variables",1,2.718);
    }
    Entry("linebreaks",
          "allowed",
          3,
          1.414
         );
}

我可以想出几种方法来解决这个问题。我可以使用正则表达式将代码“标记化”。我可以一次读一个字符的代码,然后用状态机来构造我的数据结构。我可以去掉逗号换行符,逐行阅读。我可以编写一些转换脚本,将这些代码转换为可执行的Python代码。在

有没有一种很好的pythonic方法来解析这样的文件?
你将如何解析它?在

这是一个关于如何解析字符串的一般性问题,而不是关于这个特定文件格式的问题。在


Tags: 方法代码数据结构style格式groupcommentsome
3条回答

使用pyparsing(Mark Tolonen,我正要点击“Submit Post”,当你的文章通过时),这非常简单-参见下面代码中嵌入的注释:

data = """Group("GroupName") { 
    /* C-Style comment */ 
    Group("AnotherGroupName") { 
        Entry("some","variables",0,3.141); 
        Entry("other","variables",1,2.718); 
    } 
    Entry("linebreaks", 
          "allowed", 
          3, 
          1.414 
         ); 
} """

from pyparsing import *

# define basic punctuation and data types
LBRACE,RBRACE,LPAREN,RPAREN,SEMI = map(Suppress,"{}();")
GROUP = Keyword("Group")
ENTRY = Keyword("Entry")

# use parse actions to do parse-time conversion of values
real = Regex(r"[+-]?\d+\.\d*").setParseAction(lambda t:float(t[0]))
integer = Regex(r"[+-]?\d+").setParseAction(lambda t:int(t[0]))

# parses a string enclosed in quotes, but strips off the quotes at parse time
string = QuotedString('"')

# define structure expressions
value = string | real | integer
entry = Group(ENTRY + LPAREN + Group(Optional(delimitedList(value)))) + RPAREN + SEMI

# since Groups can contain Groups, need to use a Forward to define recursive expression
group = Forward()
group << Group(GROUP + LPAREN + string("name") + RPAREN + 
            LBRACE + Group(ZeroOrMore(group | entry))("body") + RBRACE)

# ignore C style comments wherever they occur
group.ignore(cStyleComment)

# parse the sample text
result = group.parseString(data)

# print out the tokens as a nice indented list using pprint
from pprint import pprint
pprint(result.asList())

印刷品

^{pr2}$

(不幸的是,由于pyparsing定义了一个“Group”类,用于将结构传递给解析的标记,因此可能会有一些混淆-请注意,由于列表表达式包含在pyparsing组中,因此条目中的值列表是如何分组的。)

签出pyparsing。它有很多parsing examples。在

这取决于您需要它的频率以及语法是否保持不变。如果答案是“相当经常”和“或多或少是的”,那么我将研究一种表达语法的方法,并使用类似于PyPEG或{a2}的工具为该语言编写一个特定的解析器。定义解析器规则是一项艰巨的工作,因此除非您经常需要解析相同类型的文件,否则它可能不一定有效。在

但是如果你看一下PyPEG页面,它会告诉你如何将解析后的数据输出到XML,因此如果这个工具没有给你足够的能力,你可以使用它来生成XML,然后使用lxml来解析XML。在

相关问题 更多 >

    热门问题