如何使用pyparsing LineStart?

2024-10-06 15:19:46 发布

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

我尝试使用pyparsing来解析键:值对从文档中的注释。键从一行的开头开始,后面跟着一个值。值可以在以空格开头的多行上继续。在

import pyparsing as pp

instring = """
-- This is (a) #%^& comment

/*
name1: val
name2: val2 with $*&#@) junk
name3: val3: with @)(*% multi-
       line: content
*/
"""

comment1 = pp.Literal("--") + pp.originalTextFor(pp.SkipTo(pp.LineEnd())).setDebug()
identifier = pp.Word(pp.alphanums + "_").setDebug()
meta1 = pp.LineStart() + identifier + pp.Literal(":") + pp.SkipTo(pp.LineEnd())
meta2 = pp.LineStart() + pp.White() + pp.SkipTo(pp.LineEnd())
metaval = meta1 + pp.ZeroOrMore(meta2)
metalist = pp.ZeroOrMore(comment1) + pp.Literal("/*") + pp.OneOrMore(metaval) + pp.Literal("*/")

if __name__ == "__main__":
    p = metalist.parseString(instring)
    print(p)

失败原因:

^{pr2}$

pyparsing whitespace match issues的答案是

LineStart has always been difficult to work with, but ...

如果解析器位于第4行第1列(第一列键:值对),那为什么它找不到线的起点呢?正确的pyparsing语法是什么来识别以无空格开头的行和以空格开头的行?在


Tags: withpyparsingpp空格identifierliteralmeta1linestart
1条回答
网友
1楼 · 发布于 2024-10-06 15:19:46

我想我对LineStart的困惑是,对于LineEnd,我可以寻找'\n'字符,但是{}没有单独的字符。所以在LineStart中,我查看当前的解析器位置是否正好位于'\n'之后;或者如果它当前位于a'\n'上,请移过它并继续。不幸的是,我在一个混乱了报告位置的地方实现了这个,所以你会得到一些奇怪的错误,比如“在第X列1行找不到一个行的开始”,这听起来确实像是一个成功匹配的行开头。另外,我想我需要重新讨论这种隐式的换行符跳过,或者,对于LineStart来说,所有的空白都会跳过。在

现在,我已经通过稍微扩展行首表达式使您的代码正常工作,如下所示:

LS = pp.Optional(pp.LineEnd()) + pp.LineStart()

并用LS替换meta1和meta2中的LineStart引用:

^{pr2}$

如果LineStart的这种情况让您感到不舒服,那么您可以尝试另一种策略:使用解析时间条件只接受从第1列开始的标识符:

^{3}$

这段代码完全删除了LineStart,而我只想知道我希望这个特定的令牌做什么。我还必须修改ZeroOrMore中的ZeroOrMore重复,这样*/就不会被意外地处理为连续的评论内容。在

感谢您对此的耐心等待-我不希望很快给出一个修补的LineStart更改,然后发现我忽略了其他兼容性或其他边缘情况,这些情况使我重新回到了这个类的当前不太好的状态。但在发布2.1.10之前,我会花一些精力来澄清这种行为。在

相关问题 更多 >