我如何在我的CSV中使用正则表达式,以及\ N,以便mysqlimport能够理解它们?

Sea*_*ere 1 regex mysql csv import perl

假设我有一个普通的CSV

# helloworld.csv
hello,world,,,"please don't replace quoted stuff like ,,",,
Run Code Online (Sandbox Code Playgroud)

如果我想mysqlimport了解其中的一些领域NULL,那么我需要:

# helloworld.mysql.csv
hello,world,\N,\N,"please don't replace quoted stuff like ,,",\N,\N
Run Code Online (Sandbox Code Playgroud)

我从另一个问题得到了一些帮助 - 为什么sed不能取代重叠模式 - 但请注意问题:

$ perl -pe 'while (s#,,#,\\N,#) {}' -pe 's/,$/,\\N/g' helloworld.csv
hello,world,\N,\N,"please don't replace quoted stuff like ,\N,",\N,\N
                                                           ^^
Run Code Online (Sandbox Code Playgroud)

如何编写正则表达式,以便,,它们在引号之间不会被替换?

最终的回答

这是我使用的最终perl,感谢下面接受的答案:

perl -pe 's/^,/\\N,/; while (s/,(?=,)(?=(?:[^"]*"[^"]*")*[^"]*$)/,\\N/g) {}; s/,$/,\\N/' helloworld.csv
Run Code Online (Sandbox Code Playgroud)

它处理前导,尾随和不带引号的空字符串.

Eug*_*ash 7

为什么不用Text::CSV?您可以使用它解析文件,然后使用map'\ N'替换空字段,例如

use Text::CSV;

my $csv = Text::CSV->new({ binary => 1 }) or die Text::CSV->error_diag();
$csv->parse($line);           # parse a CSV string into fields
my @fields = $csv->fields();  # get the parsed fields

@fields = map { $_ eq "" ? '\N' : $_ } @fields;

$csv->combine(@fields);    # combine fields into a string
Run Code Online (Sandbox Code Playgroud)