我试图在PyParsing中解析一些非常简单的东西,但是我很难理解为什么它不起作用。我要解析的字符串如下。
string = '''START
1 10; % Name1
2 20; % Name2
END'''
我知道START和END令牌之间的每一行都包含一个或多个可能为int
或float
类型的正/负数。我还希望用户可以选择在%
符号后添加其他元数据。
所以我首先定义Floats和Names的基本语法。
Float = Word(nums + '.' + '-')
Name = Word(alphanums)
我知道一行可以包含一个或多个Float
后跟分号,也可以包含% Name
。
Line = OneOrMore(Float)('data') + Suppress(Literal(';')) + Suppress(Optional(Literal('%'))) + Optional(OneOrMore(Name)('name')) + Suppress(LineEnd())
我期待很多行,所以我可以按如下方式定义Lines的语法。
Lines = OneOrMore(Group(Line))
我按照this answer中的建议使用Group
来使检索成为可能。
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)
但是,这不会以结构化的方式返回分号后面的部分,我必须再次单独解析它。这是推荐的方法吗?
答案 0 :(得分:2)
从默认的空白字符中删除新行是解决此问题所需的。正如保罗在评论中所说,可以做出其他改进,以确保它更严格地解析浮点数和名称。
string = '''START
1 10; % Name1
2 20; % Name2
END'''
from pyparsing import Word, Keyword, nums, OneOrMore, Optional, Suppress, Literal, alphanums, LineEnd, LineStart, Group, ParserElement
ParserElement.setDefaultWhitespaceChars(" \t")
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)