换句话说,我正在寻找一种方法来忽略","在其中一个领域。
即使字段包含逗号,也应将该字段视为一个字段。
示例:
Round,Winner,place,prize
1,xyz,1,$4,500
如果我用dict阅读器阅读此内容$4,500
打印为$4
因为500
被认为是另一个字段。这是有意义的,因为我正在以逗号分隔的方式读取文件,所以我不能抱怨,但试着想办法解决。
reader = csv.reader(f, delimiter=',', quotechar='"')
我的来源没有用双引号括起来,所以我不能通过包含引号字符串来忽略。
还有其他方法可以处理这种情况吗?可能类似于定义这些美元字段并使其忽略该字段的逗号?或者试着在这个领域附近引用?
如果不是Python,可以使用shell脚本或Perl吗?
答案 0 :(得分:8)
也许预先处理数据以将所有钱包装在引号中,然后正常处理
$line =~ s/( \$\d+ (?:,\d{3})* (?:\.\d{2})? )/"$1"/gx;
该模式与$
后面的数字匹配,可选地后跟,nnn
和/或.nn
的任意倍数。它还包含$4.22
以及$100
,我认为这对于一致性很有帮助。根据需要限制匹配的内容,例如(\$\d{1,3},\d{3})
。使用小数美分删除{2}
。这并不包括所有可能的边缘/破损情况。
/g
修饰符使其替换行中的所有内容,而/x
允许空格可读。
你可以做一个单行
perl -pe 's/(\$\d+(?:,\d{3})*(?:\.\d{2})?)/"$1"/g' input.csv > changed.csv
添加-i
开关以覆盖输入(" 就地")或-i.bak
以保持备份。
如果您预计需要进一步调整或更好地记录,请将其放入脚本
use warnings;
use strict;
my $file = '...';
my $fout = '...';
open my $fh, '<', $file or die "Can't open $file: $!";
open my $fh_out, '>', $fout or die "Can't open $fout for writing: $!";
while (my $line = <$fh>) {
$line =~ s/( \$\d+ (?:,\d{3})* (?:\.\d{2})? )/"$1"/gx;
print fh_out $line;
}
close $fh;
close $fh_out;
答案 1 :(得分:1)
如果额外的,
总是存在于最后一个字段的一部分,你可以使用Bash读取循环:
#!/bin/bash
while IFS=, read -r f1 f2 f3 f4; do
# f4 => has everything after f3, including extra commas as in $4,500
# do your processing
printf "f1=[$f1] f2=[$f2] f3=$[f3] f4=[$f4]\n"
done < input.txt
输入:
1,xyz,1,$4,500
2,abc,3,$400
输出:
f1=[1] f2=[xyz] f3=1 f4=[$4,500]
f1=[2] f2=[abc] f3=3 f4=[$400]