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