我有以下语法:
kv = Word(alphanums + '_') | QuotedString('"', escQuote="\\") | QuotedString("'", escQuote="\\")
kv = kv.setResultsName('literal', listAllMatches=True)
cskv = kv + Optional(ZeroOrMore(Suppress(',') + kv)) # comma separated kv
并使用此示例:
>>> res=cskv.parseString('a,b,c,d,e')
>>> res
(['a', 'b', 'c', 'd', 'e'], {'literal': [('a', 0), ('b', 1), ('c', 2), ('d', 3), ('e', 4)]})
>>> res[0]
'a'
>>> type(res[0])
<type 'str'>
通知:
>>> type(res[0])
<type 'str'>
我真的希望它是ParseResults
,而不是字符串,这样我就可以res[0].getName()
,希望我能得到literal
。
第二个问题是如何获得某些令牌的索引?
假设我想知道literal d
的索引,它应该返回3
。
在这个例子中它是微不足道的,因为我只有一种类型的令牌,但在我的问题中,我需要知道不同类型的令牌的相对位置,以便在处理时有所帮助。
任何实现这些目标的方法?
我不知道为什么我的问题如此令人困惑,为什么人们会继续关注我的例子而不是我的问题。以下是更加明确的说明:
我使用pyparsing作为一个标记器来标记一个字符串来解释它,我遇到的问题是,我需要知道那个标记是什么,让我们说(这意味着它是一个不值得关注的例子) ):
variable = string
如果某种语言支持这一点,并且它知道字符串恰好是一个左值,那么它就是一个变量,如果它是正确的值它将是一个字符串(不要问我为什么是这样,它已经组成了)。
所以我期待这种语法:
expr = Word(alphanums+'_')('leftval') + '=' + Word(alphanums+'_')('rightval')
最后,该表达式应该被完全标记化:
In [3]: res = expr.parseString('variable = string')
In [4]: res
Out[4]: (['variable', '=', 'string'], {'rightval': [('string', 2)], 'leftval': [('variable', 0)]})
但这是我的问题:
In [5]: res[0]
Out[5]: 'variable'
In [6]: type(res[0])
Out[6]: str
现在res
给了我一个字符串。我需要一个令牌工作器,包括令牌后面的信息,现在我丢失了令牌的名称,该名称应为leftval
。
有趣的是,__repr__
的{{1}}已显示我需要的所有信息:
令牌名称,以及所有捕获的令牌本身以及令牌化结果res
中的位置。
看到了吗?
这正是我的问题。不是如何用pyparsing处理逗号分隔值。
答案 0 :(得分:0)
我不确定这是否能回答你的问题
from pyparsing import Word, alphas,alphanums,QuotedString,Optional,ZeroOrMore,Suppress
kv = Word(alphanums + '_') | QuotedString('"', escQuote="\\") | QuotedString("'", escQuote="\\")
kv = kv.setResultsName('literal', listAllMatches=True)
cskv = kv + Optional(ZeroOrMore(Suppress(',') + kv)) # comma separated kv
tokens = cskv.parseString("a,b,c,d,e")
#you can use asDict to get a dictionary mapping names to values
print tokens.asDict()
#or you can get it as xml and parse the xml
import re
xml_result = tokens.asXML()
for tok in tokens:
needle = "\<([^\>]+)\>\s*%s\s*\<\/"%tok
print tok, "=", re.search(needle,xml_result).groups()[0]
可能有更好的方法来做到这一点......我不确定......它也可能会破坏更复杂的语法......
根据您的评论尝试
import ast
parsed_values,meta_data = ast.literal_eval(repr(tokens))
print parsed_values # ['a', 'b', 'c', 'd', 'e']
print meta_data # {'literal': [('a', 0), ('b', 1), ('c', 2), ('d', 3), ('e', 4)]}
答案 1 :(得分:0)
根据pyparsing文档,存在 delimitedList 函数,它用于解析由特定分隔符分隔的多个字符组成的特定字符串。
我会引用它:
帮助器定义分隔符表达式列表 - 分隔符默认为“,”。默认情况下,列表元素和分隔符可以有插入的空格和注释,但这可以通过在构造函数中传递combine = True来覆盖。如果将combine设置为True,则匹配的标记将作为单个标记字符串返回,并包含分隔符;否则,匹配的标记将作为标记列表返回,并且分隔符被抑制。
现在你只需要使用它并使用它解析一个字符串来获取 ParseResult 对象:
csvExpr = delimitedList()
parsed = csvExpr.parseString("a,b,c,d,e")
print(type(parsed)) # output: <class 'pyparsing.ParseResults'>