Python解析问题

时间:2015-11-26 10:04:02

标签: python python-2.7

我需要将.format()转换为类似

的字符串
a = "01AA12345AB12345AABBCCDDEE".reverseformat({id:2d}{type:2s}{a:3d}{b:4s}{c:5d}{d:2s})
print a

>>>> {'id':1, 'type':'aa', 'a':'123', 'b':'45AB', 'c':'12345', 'd':'AA'} 

我发现this lib几乎可以满足我的需要,问题是它给了我这个结果

msg = parse.parse("{id:2d}{type:3S}{n:5S}", "01D1dddffffffff")

print msg.named

>>>>{'type': 'D1dddfffffff', 'id': 1, 'n': 'f'}

而不是

{'id':1, 'type':'D1d', 'n':'ddfffff'}

是否有另一个可以将字符串“解包”到字典的lib / method / wathever?

编辑:为了澄清,我已经尝试了字符串

的w和D格式规范

2 个答案:

答案 0 :(得分:4)

如果您的格式始终相同,是否有任何理由可以像普通字符串一样将其切片?

s = "01D1dddffffffff"
id = s[:2]
type = s[2:5]
n = s[5:]

其中id,type和n为:

01
D1d
ddffffffff

如果你需要的话,将它转换成字典是微不足道的。如果你的解析不需要是动态的(它似乎不是来自你问题的当前状态)那么它很容易将切片包装在一个函数中这将提取所有的值。

这也有一个好处,就是从切片中可以清楚地知道有多少个字符以及你要提取的字符串中的位置,但是在解析格式化程序中,这些位置都是相对的(即查找哪些字符{ {1}}提取意味着计算nid消耗的字符数。)

答案 1 :(得分:2)

您可以使用正则表达式在此处执行所需操作。

import re

a = "01AA12345AB12345AABBCCDDEE"
expr = re.compile(r"""
    (?P<id>.{2})          # id:2d
    (?P<type>.{2})        # type:2s
    (?P<a>.{3})           # a:3d
    (?P<b>.{4})           # b:4s
    (?P<c>.{5})           # c:5d
    (?P<d>.{2})           # d:2s""", re.X)

expr.match(a).groupdict()
# {'id': '01', 'b': '45AB', 'c': '12345', 'd': 'AA', 'a': '123', 'type': 'AA'}

你甚至可以制作一个能够做到这一点的功能。

def unformat(s, formatting_str):
    typingdict = {'s': str, 'f': float, 'd':int}  # are there any more?
    name_to_type = {}
    groups = re.findall(r"{([^}]*)}", formatting_str)
    expr_str = ""
    for group in groups:
        name, formatspec = group.split(":")
        length, type_ = formatspec[:-1], typingdict.get(formatspec[-1], str)
        expr_str += "(?P<{name}>.{{{length}}})".format(name=name, length=length)
        name_to_type[name] = type_
    g = re.match(expr_str, s).groupdict()
    for k,v in g.items():
        g[k] = name_to_type[k](v)

    return g

然后打电话给......

>>> a
'01AA12345AB12345AABBCCDDEE'
>>> result = unformat(a, "{id:2d}{type:2s}{a:3d}{b:4s}{c:5d}{d:2s}")
>>> result
{'id': 1, 'b': '45AB', 'c': 12345, 'd': 'AA', 'a': 123, 'type': 'AA'}

但是我希望你能看到这是多么难看的丑陋。不要这样做 - 只需使用字符串切片。