如何使用动态列数重新格式化数据

时间:2012-12-05 10:39:12

标签: python bash text-parsing

我的数据格式是类别和值在同一行中以“;”分隔如下:

{{category1;value}, {category2;value}, {category3;value} ....}}

在每一行上,数据可能有不同数量的类别。因此,第一行可以具有category1到category5,而第二行可以具有category1到category10。这些类别总是按顺序排列。

我需要解析数据并创建一个新文件,这样我就可以在列标题中找到类别的名称,并在相应的行中输入值。

category1        category2        category3       category4    ....
 value             value             value          value

但是由于我不能说可能有多少类别,我需要添加每个新列。因此,解析第一行我会知道有5列(cat1到cat5),但对于第二行,我必须将cat6的列添加到cat10,依此类推。

知道如何做到这一点。任何Linux bash脚本都可以,但python会比我更好。

2 个答案:

答案 0 :(得分:1)

鉴于评论,听起来category可以包含分号以外的任何字符,而value可以包含除括号之外的任何字符,因为这些字符将终止{{1或者category太快了。

在这种情况下,可以使用正则表达式来匹配模式。

value

产量

import re

def report(text):
    # Remove surrounding whitespace and braces
    text = text.strip()[1:-1]   
    pairs = re.findall(
        r'''\{      # literal open brace
            (.+?)   # one-or-more characters, stop at the first
            ;       # literal semicolon
            (.+?)   # one-or-more characters, stop at the first
            \}      # literal closed brace
            ''', text, re.VERBOSE)
    categories, values = zip(*pairs)
    widths = [max(map(len, item)) for item in pairs]
    fmt = '{x:^{w}}'
    for row in (categories, values):
        print('    '.join([fmt.format(x = x, w = w) for x, w in zip(row, widths)]))

tests = """\
{{category1;value}, {category2;value}}
{{category1;value}, {category2;value}, {category3;value}}
{{categ{,ory1;val;ue}, {category2;val{ue}, {category3;value}}
""".splitlines()

for test in tests:
    report(test)

答案 1 :(得分:0)

可能有多种方法可以做到,但可能的方法是

>>> rows = data.translate(None,"{}").replace(";",",").split(",")
>>> rows[::2]
['category1', ' category2', ' category3']
>>> rows[1::2]
['value', 'value', 'value']

以及上面的一小部分

>>> rows = dict(e.split(';') for e in data.translate(None,"{}").split(","))
>>> rows.keys()
['category1', ' category2', ' category3']
>>> rows.values()
['value', 'value', 'value']

使用正则表达式的另一种变体

>>> rows = re.split("[\{\},; ]+",data)[1:-1]
>>> rows[::2]
['category1', 'category2', 'category3']
>>> rows[1::2]
['value', 'value', 'value']