Perl 和正则表达式来救援。挖掘 SO,并玩弄正则表达式here,想出正确的一个并不难:
s/(\"[^\",]+),([^\"]+\")/$1_$2/g
哪个匹配"...,..."
,这里的点不是双引号和逗号,而是用下划线替换逗号。 Perl 单行过滤器是传递给 sqldf 的正确过滤器:
x <- read.csv.sql("temp.csv",
filter = "perl -e 's/(\"[^\",]+)_([^\"]+\")/$1_$2/g'",
header=FALSE)
这是数据框x
> x
V1 V2 V3 V4
1 1001 Amy 9:43:00 99.2
2 1002 "Ben_Jr" 9:43:00 99.2
3 1003 "Ben_Sr" 9:44:00 99.3
现在,DYO 琴弦上的化妆品......
EDIT:上面的正则表达式仅替换字段中第一次出现的逗号。要替换所有发生的情况,请使用此
s{(\"[^\",]+),([^\"]+\")}{$_= $&, s/,/_/g, $_}eg
有什么不同?
- 我替换了分隔符
/
with {}
;
- 最后的选项 e 指示解析器将替换字段解释为 perl 代码;
- 替换是一个简单的正则表达式替换,替换所有“
,
" with "_
" 在匹配的子字符串中$&
.
一个例子:
system("touch temp.csv")
system("echo '1001, Amy,9:43:00, 99.2\n1002,\"Ben,Jr,More,Commas\",9:43:00, 99.2\n1003,\"Ben,Sr\",9:44:00, 99.3' > temp.csv")
文件 temp.csv 如下所示:
1001, Amy,9:43:00, 99.2
1002,"Ben,Jr,More,Commas",9:43:00, 99.2
1003, "Ben,Sr",9:44:00, 99.3
并且可以阅读
x <- read.csv.sql("temp.csv",
filter = "perl -p -e 's{(\"[^\",]+),([^\"]+\")}{$_= $&, s/,/_/g, $_}eg'",
header=FALSE)
> x
V1 V2 V3 V4
1 1001 Amy 9:43:00 99.2
2 1002 "Ben_Jr_More_Commas" 9:43:00 99.2
3 1003 "Ben_Sr" 9:44:00 99.3