【发布时间】:2020-03-16 01:36:11
【问题描述】:
我必须处理由专有软件创建的格式错误的 csv 文本文件,该软件会更改某些格式(引号、列分隔符、单个小数位浮动到四个小数位和换行符)。我的目标输出是制表符分隔的,unix 换行符和浮点数。
以下是原始文件中的一些示例行:
1234\t5678\t-3461\t56\t10\n
4435.5\t-1261\t56\t10\n
89432\t678112\t-2461\t56\t10\n
这是专有软件的输出(不一定是 4 个十进制浮点数的固定宽度,开发人员可能会在未来的版本中更改此设置):
"1234.0000 5678.0000 -3461.0000 56.0000 10.0000"\r
"4435.5000 -1261.0000 56.0000 10.0000"\r
"89432.0000 678112.0000 -2461.0000 56.0000 10.0000"\r
我在函数中的模式非常冗长,正则表达式可能会写得更简洁,但由于我对正则表达式还不是很熟悉,所以我倾向于保持模式简单易懂。这是我用来重组 csv 文件的每一行的函数:
import re
def Filter(inputLine):
line = inputLine.strip().lstrip("'").rstrip("'").lstrip('"').rstrip('"') #get rid of internal quotation marks and newline character
line = re.sub(r'\s','\t', line) #replace whitespaces by tab
line = re.sub(r'\.0{1,9}','', line) #replace all .0* by single whitespace - not really working, .5000 for example - think!
line = f'{line}\n'
return(line)
#code for parsing each oline of input and so on
到目前为止一切顺利,但正如预期的那样,这不会将第 2 行中的 4435.5000 更改为 4435.5:
1234\t5678\t-3461\t56\t10\n
4435.5000\t-1261\t56\t10\n
89432\t678112\t-2461\t56\t10\n
我想在这个任务中使用正则表达式,即使对于大 (>1GB) 文本文件也有效(我不知道是否有更优雅的解决方案来处理这个操作)。
- 保持 0.5 但删除所有 0.000 的模式是什么?我正在考虑以下内容,但我被替换部分卡住了:
line = re.sub(r'\.[1-9]0{1,9}',r'\.[1-9]', line)
这显然行不通。
- 有什么方法可以压缩正则表达式模式?这更出于兴趣,正如我上面提到的,我目前更喜欢单独调用来帮助我理解正则表达式的语法。
欢迎提出任何建议!
干杯 萨沙
【问题讨论】:
-
line = re.sub(r'(\.(\d*?))0+', lambda x: x.group(1) if x.group(2) else '', line)(demo) -
@WiktorStribiżew 哇!这是一个超级高效的 python 和正则表达式的非常酷的组合。非常感谢,这解决了我的问题。
标签: regex python-3.x csv