【发布时间】:2014-01-04 23:18:52
【问题描述】:
无聊的背景故事:
我的银行报告有 .pdf 和 .csv 格式,但旧的报告只能以 pdf 格式提供给我。我想以与新数据相同的格式保存数据,以便更容易搜索,但 pdf 受到保护,在使用解锁器和 pdf 到文本转换器后,我最终得到了格式非常糟糕的文件。
我有文件,其中每一行都是一个事务(例如:23.12 22.12.09 Verfügung Geldautomat\t63050000 / 9000481400\tGA NR00002317 BLZ63050000 0\t22.12/14.17UHR ESELSBERGW EUR 50,00\t-50,00)
将数据字段替换为数字会产生以下顺序和分隔符:
1 2 3\t7 / 6\t5\t4\t8
但我想要这种格式(原始数据中不存在的字段 0、9 和 10 是静态的)
"0";"1";"3";"4";"5";"6";"7";"8";"9";"10"
这是我目前的方法(没有 I/O 部分)
def readtrans(line):
d1, d2, rest = line.split(' ', 2)
d3, rest, d5, d4, d8 = rest.split('\t')
d7, d6 = rest.split(' / ')
return [d1, d2, d3, d4, d5, d6, d7, d8]
不幸的是,它在第一个文件的第 3 行崩溃了,因为字段 3 的某些值的字段 5 和 6 是空的。在添加 if 子句来解决这个问题后,脚本前进到第 5 行只是再次崩溃,因为字段 4 也可能包含选项卡。我也可以解决这个问题,但我将其作为寻找更灵活解决方案的线索。
大多数时候,当我需要从文本中提取数据时,我会相应地查看分隔符和split()。它可能效率不高,但比查找我很少使用并反复忘记的正则表达式语法要快。在这种情况下这是一种可行的方法还是正则表达式更适合?正则表达式甚至可以处理此任务,如果可以,它仍然可读吗?你会怎么解决呢?
编辑: 这是真的,我永远不会再使用这个代码,(顺便说一句,这是我的解决方案)但这是一个非常常见的问题
def readtrans(line):
d1, d2, rest = line.split(' ', 2)
if rest[0] == 'A':
d3, d7, d4, d8 = rest.split('\t')
d5 = ''
d6 = ''
else:
d3, d7d6, d5, d4d8 = rest.split('\t', 3)
d7, d6 = d7d6.split(' / ')
rest = d4d8.split('\t')
d8 = rest[-1]
d4 = ' '.join(rest[:-1])
return [d1, d2, d3, d4, d5, d6, d7, d8]
在思考如何改写我的问题后,我意识到它基本上是这个Convert string to variables (like format(), but in reverse)的复制品
有了新知识,我制作了这个正确解析我的示例的简短模式
import re
example = '23.12 22.12.09 Verfügung Geldautomat\t63050000 / 9000481400\tGA NR00002317 BLZ63050000 0\t22.12/14.17UHR ESELSBERGW EUR 50,00\t-50,00'
x = re.search(r'(\S+) (\S+) ([\S| ]+)\t(\S+) / (\S+)\t([\S| ]+)\t([\S| ]+)\t([\S| ]+)', example)
print x.groups()
>>>('23.12',
'22.12.09',
'Verf\xc3\xbcgung Geldautomat',
'63050000',
'9000481400',
'GA NR00002317 BLZ63050000 0',
'22.12/14.17UHR ESELSBERGW EUR 50,00',
'-50,00')
关键是使用 re.groups()
【问题讨论】:
-
您能否用一些导致代码崩溃的行示例更新您的问题?此外,StackOverflow 可能正在吞噬你的
\t字符,所以如果你能明确指出这些字符的去向,那就太好了。 -
不要忘记 try/except 有利于处理预期的错误。
-
@senshin:错误是由于拆分产生的元素比预期的多或少,正如我所说,我可以解决这些问题,但我对提取具有不同模式的多个子字符串的一般方法更感兴趣,而不是这个特定的问题。
标签: python regex string-parsing