Pyparsing - 当令牌顺序不可预测时
我想从一段文本中提取出字母的类型和数量,而这些字母的顺序可能是随意的。虽然我已经有其他的解析部分在正常工作,但这一部分让我感到困惑!
input -> result
"abc" -> [['a',1], ['b',1],['c',1]]
"bbbc" -> [['b',3],['c',1]]
"cccaa" -> [['a',2],['c',3]]
我可以使用搜索或扫描的方法,对每一个可能的字母进行重复操作,但有没有更简单的方法呢?
这是我目前的进展:
from pyparsing import *
def handleStuff(string, location, tokens):
return [tokens[0][0], len(tokens[0])]
stype = Word("abc").setParseAction(handleStuff)
section = ZeroOrMore(stype("stype"))
print section.parseString("abc").dump()
print section.parseString("aabcc").dump()
print section.parseString("bbaaa").dump()
5 个回答
3
Alex提到的另一个不错的选择,适合你使用3.1版本。
还有一个选择是collections.defaultdict:
>>> from collections import defaultdict
>>> mydict = defaultdict(int)
>>> for c in 'bbbc':
... mydict[c] += 1
...
>>> mydict
defaultdict(<type 'int'>, {'c': 1, 'b': 3})
6
一种解决方案:
text = 'sufja srfjhvlasfjkhv lasjfvhslfjkv hlskjfvh slfkjvhslk'
print([(x,text.count(x)) for x in set(text)])
这里没有使用pyparsing这个库,不过看起来这个方法有点复杂。
6
我不太清楚你描述的输入字符是否可以像“ababc”这样混合,因为在你所有的测试案例中,字母总是被分组在一起。如果字母确实总是分组在一起,你可以使用下面的pyparsing代码:
def makeExpr(ch):
expr = Word(ch).setParseAction(lambda tokens: [ch,len(tokens[0])])
return expr
expr = Each([Optional(makeExpr(ch)) for ch in "abc"])
for t in tests:
print t,expr.parseString(t).asList()
这个Each构造可以处理字符顺序不一致的情况,而Word(ch)则负责处理字符的重复次数。解析动作会把解析出来的内容转换成(字符, 计数)这样的元组。