多行 PyParsing 示例
Multiline PyParsing example
我正在尝试在多行的 PyParsing 中解析一些非常简单的东西,但我很难理解为什么它不起作用。我要解析的字符串如下
string = '''START
1 10; % Name1
2 20; % Name2
END'''
我知道 START 和 END 标记之间的每一行都将包含一个或多个可以是 int
或 float
类型的正数/负数。我还希望用户可以选择在 %
符号后添加其他元数据。
所以我首先定义浮点数和名称的基本语法。
Float = Word(nums + '.' + '-')
Name = Word(alphanums)
我知道一行可以包含一个或多个 Float
后跟一个分号,并且可以选择 % Name
.
Line = OneOrMore(Float)('data') + Suppress(Literal(';')) + Suppress(Optional(Literal('%'))) + Optional(OneOrMore(Name)('name')) + Suppress(LineEnd())
我希望有很多行,所以我可以如下定义行的语法。
Lines = OneOrMore(Group(Line))
我按照 Paul 在 中的建议使用 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)
但是,这并不是 return 分号后的结构化部分,我必须再次单独解析它。这是推荐的方法吗?
从默认空白字符中删除新行是解决此问题所需要的。正如 Paul 在他的评论中所建议的那样,可以进行其他改进以确保它更严格地解析浮点数和名称。
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)
我正在尝试在多行的 PyParsing 中解析一些非常简单的东西,但我很难理解为什么它不起作用。我要解析的字符串如下
string = '''START
1 10; % Name1
2 20; % Name2
END'''
我知道 START 和 END 标记之间的每一行都将包含一个或多个可以是 int
或 float
类型的正数/负数。我还希望用户可以选择在 %
符号后添加其他元数据。
所以我首先定义浮点数和名称的基本语法。
Float = Word(nums + '.' + '-')
Name = Word(alphanums)
我知道一行可以包含一个或多个 Float
后跟一个分号,并且可以选择 % Name
.
Line = OneOrMore(Float)('data') + Suppress(Literal(';')) + Suppress(Optional(Literal('%'))) + Optional(OneOrMore(Name)('name')) + Suppress(LineEnd())
我希望有很多行,所以我可以如下定义行的语法。
Lines = OneOrMore(Group(Line))
我按照 Paul 在 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)
但是,这并不是 return 分号后的结构化部分,我必须再次单独解析它。这是推荐的方法吗?
从默认空白字符中删除新行是解决此问题所需要的。正如 Paul 在他的评论中所建议的那样,可以进行其他改进以确保它更严格地解析浮点数和名称。
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)