我在使用pyparsing时遇到了一些基本问题。下面是测试程序和运行的输出。
aaron-mac:sql aaron$ more s.py
from pyparsing import *
n = Word(alphanums)
a = Group( n | Group( n + OneOrMore( Suppress(",") + n )))
p = Group( a + Suppress(".") )
print a.parseString("first")
print a.parseString("first,second")
print p.parseString("first.")
print p.parseString("first,second.")
aaron-mac:sql aaron$ python s.py
[['first']]
[['first']]
[[['first']]]
Traceback (most recent call last):
File "s.py", line 15, in <module>
print p.parseString("first,second.")
File "/Library/Python/2.6/site-packages/pyparsing.py", line 1032, in parseString
raise exc
pyparsing.ParseException: Expected "." (at char 5), (line:1, col:6)
aaron-mac:sql aaron$
如何修改测试程序中的语法以解析以句点终止的逗号分隔名称列表?我查看了文档,并试图找到一个实时支持列表,但我决定在这里得到回复。
答案 0 :(得分:5)
'|' operator创建一个MatchFirst表达式,在该表达式中,在第一次匹配之前评估备选方案。
Pyparsing纯粹从左到右工作,尽可能将解析器表达式应用于输入字符串。 pyparsing唯一的前瞻是你写入解析器的任何东西。
在这个表达式中:
a = Group( n | Group( n + OneOrMore( Suppress(",") + n )))
假设n
只是文字“X”。如果给这个解析器输入字符串“X”,它显然会匹配前导的单独n
表达式。如果给定字符串“X,X,X”,它仍然只匹配前导n
,因为这是解析器中的第一个替代。
如果将表达式转为:
a = Group( Group( n + OneOrMore( Suppress(",") + n )) | n)
然后解析“X”它会首先尝试匹配列表,这将失败,然后匹配单独的n
。要解析“X,X,X”,第一个选择将是列表表达式,它将匹配。
如果您想要匹配最长的替代方法,请使用'^'运算符,它提供Or表达式。或者将评估所有给定的替代方案,然后选择最长的匹配。
a = Group( n ^ Group( n + OneOrMore( Suppress(",") + n )))
您还可以使用pyparsing helper方法delimitedList
来简化此操作。解析用逗号分隔的相同表达式的列表是一种常见的情况,因此我不是要看到人们不得不一遍又一遍地重新发明expr + ZeroOrMore(Suppress(",") + expr)
,而是将delimitedList
添加为标准的pyparsing助手。 delimitedList("X")
将匹配“X”和“X,X,X”。
答案 1 :(得分:2)
如果您只想介绍以句号分隔的逗号分隔名称列表,您可以使用以下内容:
from pyparsing import *
p = Word(alphanums)+ZeroOrMore(Suppress(",")+Word(alphanums))+Suppress(".")
通过这种方式,您可以获得以下结果:
>>> print p.parseString("first.")
['first']
>>> print p.parseString("first,second.")
['first', 'second']
您问题中的其他示例会失败,因为它们不会以句点结束。