0
我想解析一些非常简单的PyParsing,这是多行,但我挣扎明白为什么它不工作。我想解析的字符串如下。多行PyParsing示例
string = '''START
1 10; % Name1
2 20; % Name2
END'''
我知道,开始和结束标记之间每行包含一个或多个正/负号,可以是int
或float
类型。我也希望用户可以选择在%
符号后添加额外的元数据。
所以我首先定义了Floats和Names的基本语法。
Float = Word(nums + '.' + '-')
Name = Word(alphanums)
我知道一个线可以由% Name
包含随后分号一个或多个Float
,以及任选。
Line = OneOrMore(Float)('data') + Suppress(Literal(';')) + Suppress(Optional(Literal('%'))) + Optional(OneOrMore(Name)('name')) + Suppress(LineEnd())
我预计很多行,所以我可以定义行的语法如下。
Lines = OneOrMore(Group(Line))
我用Group
如保罗在this answer建议,使检索成为可能。
grammar = Suppress(Keyword('START')) + Lines + Suppress(Keyword('END'))
grammar.parseString(string)
然而,这将引发写着低于以下
ParseException: Expected end of line (at char 62), (line:3, col:19)
的完整代码更容易复制和粘贴错误。
string = '''START
1 10; % Name1
2 20; % Name2
END'''
from pyparsing import Word, Keyword, nums, OneOrMore, Optional, Suppress, Literal, alphanums, LineEnd, LineStart, Group
Float = Word(nums + '.' + '-')
Name = Word(alphanums)
Line = OneOrMore(Float)('data') + Suppress(Literal(';')) + Suppress(Optional(Literal('%'))) + Optional(OneOrMore(Name)('name')) + Suppress(LineEnd())
Lines = OneOrMore(Group(Line))
grammar = Suppress(Keyword('START')) + Lines + Suppress(Keyword('END'))
grammar.parseString(string)
编辑:
我已经尝试了以下无济于事无论是。
string = '''START
1 10; % Name1
2 20; % Name2
END'''
from pyparsing import Word, Keyword, nums, OneOrMore, Optional, Suppress, Literal, alphanums, LineEnd, LineStart, Group
Float = Word(nums + '.' + '-')
Name = Word(alphanums)
NL = Suppress(LineEnd())
Line = OneOrMore(Float)('data') + Suppress(Literal(';')) + Optional(~NL +
Suppress(Literal('%'))
+ OneOrMore(Name)('name') + NL) | NL
Lines = OneOrMore(Group(Line))
grammar = Suppress(Keyword('START')) + Lines + Suppress(Keyword('END'))
grammar.parseString(string)
,它似乎工作的唯一的事情是,如果我用restOfLine
Line = OneOrMore(Float)('data') + Suppress(Literal(';')) + Optional(restOfLine)
然而,这并不在一个结构化的方式分号后返回的部分,我必须分析它再分开。这是推荐的方法吗?
添加“Name.setDebug()”和“Float.setDebug()”,看看该输出是否有用。 – PaulMcG
这个输出似乎表明'OneOrMore(Name)'比行尾更进一步。推荐的方法是确保OneOrMore(Name)在行尾停止。我尝试了OneOrMore(Name)+ NL,但这也没有奏效,我无法理解为什么。 – kdheepak
首先,是“2”的有效名称吗?其次,语法结尾是否有意义?如果是这样,那么您应该使用ParserElement.setDefaultWhitespaceChars(请参阅https://pythonhosted.org/pyparsing/pyparsing.ParserElement-class.html#setDefaultWhitespaceChars中的文档内联示例)将它们从可忽略的空白集中移除。最后,你可能想要收紧Float和Name的定义。就像你现在拥有它们一样,Float将匹配诸如“......”,“---”和“1.1”之类的字符串。1“,名称将匹配”12345“和”221B“ – PaulMcG