0

我正在尝试解析以下文件(从本地银行导出的交易):

Clnr   Kontonr     Konto                Valuta  Bokföringsdatum  Transaktionsdatum  Referens                            Kontohändelse                   Belopp
12345  1234567890  vardagskonto         SEK     13-09-30         13-09-30           Hyresgästför                        Autogiro                        -15,00
12345  1234567890  vardagskonto         SEK     13-09-30         13-09-30           SPOTIFY SPOTIFY                     Kortköp/uttag                   -19,00
12345  1234567890  vardagskonto         SEK     13-09-30         13-09-30           +46123456789                        Swish mottagen                   80,00
12345  1234567890  vardagskonto         SEK     13-09-30         13-09-30           PRIS NYCKELKUND                     Debiteringsavgift               -49,00
12345  1234567890  vardagskonto         SEK     13-09-27         13-09-27           12345678                            direktbetalning                -301,00
12345  1234567890  vardagskonto         SEK     13-09-27         13-09-27           Unionen                             Bg-bet. via internet           -125,00
12345  1234567890  vardagskonto         SEK     13-09-26         13-09-26           123456789012345                     Överföring                   -1 000,00

但我似乎无法为它创建一个合适的正则表达式。目标是提取第 5、6、7 和 9 列(如果可以全部提取,那当然是一个奖励),但第 7 列是非常棘手的,因为文件不是 CSV 并且第 7 列可以包含多个词。第 8 列是不可预测的,但我想我在上面的例子中找到了大部分相关的可能性。

有关如何成功解析此文件的任何提示?显然我的正则表达式是不够的。:-(

如果它有任何区别,我希望它可以在 Python 甚至 POSIX(grep/sed/etc)中解决。

4

3 回答 3

1

您可以使用re.split来分隔值。例子:

import re

raw_data = open("test.csv").readlines()
header = raw_data[0]
data = raw_data[1:]

for line in data:
        values = re.split("\s{2,}", line.strip()) # splits by two or more spaces
        print list(values) # show as a list
于 2013-10-06T11:25:37.360 回答
1

只是为了它,这就是您可以“自动”解析这种格式的方式:

import re

# find out spaces' positions common to all rows
spaces = sorted(set.intersection(*[
    set(m.end() for m in re.finditer(ur'\s', line))
    for line in data
]))

# split by these positions
for line in data:
    row = []
    p = 0
    for s in spaces:
        row.append(line[p:s])
        p = s
    row.append(line[p:])
    row = filter(len, map(unicode.strip, row))
    print ' | '.join(row) # or whatever you want...

对于您的数据:

data = u"""
Clnr   Kontonr     Konto                Valuta  Bokföringsdatum  Transaktionsdatum  Referens                            Kontohändelse                   Belopp
12345  1234567890  vardagskonto         SEK     13-09-30         13-09-30           Hyresgästför                        Autogiro                        -15,00
12345  1234567890  vardagskonto         SEK     13-09-30         13-09-30           SPOTIFY SPOTIFY                     Kortköp/uttag                   -19,00
12345  1234567890  vardagskonto         SEK     13-09-30         13-09-30           +46123456789                        Swish mottagen                   80,00
12345  1234567890  vardagskonto         SEK     13-09-30         13-09-30           PRIS NYCKELKUND                     Debiteringsavgift               -49,00
12345  1234567890  vardagskonto         SEK     13-09-27         13-09-27           12345678                            direktbetalning                -301,00
12345  1234567890  vardagskonto         SEK     13-09-27         13-09-27           Unionen                             Bg-bet. via internet           -125,00
12345  1234567890  vardagskonto         SEK     13-09-26         13-09-26           123456789012345                     Överföring                   -1 000,00
""".strip().splitlines()

这打印:

Clnr | Kontonr | Konto | Valuta | Bokföringsdatum | Transaktionsdatum | Referens | Kontohändelse | Belopp
12345 | 1234567890 | vardagskonto | SEK | 13-09-30 | 13-09-30 | Hyresgästför | Autogiro | -15,00
12345 | 1234567890 | vardagskonto | SEK | 13-09-30 | 13-09-30 | SPOTIFY SPOTIFY | Kortköp/uttag | -19,00
12345 | 1234567890 | vardagskonto | SEK | 13-09-30 | 13-09-30 | +46123456789 | Swish mottagen | 80,00
12345 | 1234567890 | vardagskonto | SEK | 13-09-30 | 13-09-30 | PRIS NYCKELKUND | Debiteringsavgift | -49,00
12345 | 1234567890 | vardagskonto | SEK | 13-09-27 | 13-09-27 | 12345678 | direktbetalning | -301,00
12345 | 1234567890 | vardagskonto | SEK | 13-09-27 | 13-09-27 | Unionen | Bg-bet. via internet | -125,00
12345 | 1234567890 | vardagskonto | SEK | 13-09-26 | 13-09-26 | 123456789012345 | Överföring | -1 000,00
于 2013-10-06T11:48:50.753 回答
-1

为什么不是这个正则表达式:

(.*?)(  +|\r\n|\n|$)

似乎所有列都由 2 个空格分隔

于 2013-10-06T11:19:06.263 回答