2013-06-25 65 views
6

我有一个记录集,看起来像这样与管道替换逗号,但不包括在双引号

"BOSW0001","Mr","Wayne","Boswell","Wayne,Jessica & Lyn","31 Baker St" 
"ELLI0007","Mrs","Bronwyn","Elliott","Bronwyn, Paul & Arianne","98A Dandaraga Rd" 
"KENN0001","Mr","Leigh","Kenning","Leigh & Beth,Cole","22 Lake St" 

逗号我想无需更换逗号来代替逗号(,)与管(|

"Leigh & Bethie,Coles" 
"Waynez,Jessy & Lyne" 
"Bronwynie, Paula & Arianne" 

我该如何使用正则表达式或其他方法来做到这一点?

回答

12

你不使用正则表达式做到这一点;你用一个适当的CSV解析器来做。这是一个使用Text::CSV_XS(未经测试)的例子 - 业内最好的。

use strict; 
use warnings; 

use Text::CSV_XS; 

my $in_file = "whatever.csv"; 
my $out_file = "new.dat"; 

open my $fh, '<', $in_file or die "$in_file: $!"; 
open my $out_fh, '>', $out_file or die "$out_file: $!"; 

my $in_csv = Text::CSV_XS->new; 
my $out_csv = Text::CSV_XS->new({ sep_char => '|', eol => "\n" }); 

while(my $row = $in_csv->getline($fh)) { 
    $out_csv->print($out_fh, $row); 
} 
+3

在你未经测试的例子中实际上有3个错误:1.'readline'应该是'getline'; 2.'new'的选项应该在hashref中,即'new({sep_char =>'|'})'; 3.您可能需要指定'eol'选项(默认为'$ \','$ \'为默认的undef),以防止将所有行打印在一行中。也许你可以使用'new({sep_char =>'|',eol => $ /})''。 – doubleDown

+1

@doubleDown谢谢 - 更新。 – friedo

0

如何利用出现的逗号(双引号之间)的范围内:

s/","/"|"/g 
+1

如果一条记录包含一个转义引号和一个逗号,该怎么办? – friedo

+0

@paddy这个完美的作品,如果使用正则表达式 谢谢 – Soncire

+0

没问题。它并不是那么受欢迎(我的评分差不多达到了最高),因为有几个不太可能的情况会发生。但是,您通常知道有关您的数据的某些内容,而且快速,简单的解决方案已足够好。事实上,比在一个可能不需要的更复杂的解决方案上花费大量时间更好。 – paddy

6

只是为了TIMTOWTDI的缘故,这里是一个使用核心模块Text::ParseWords一个例子。

#!/usr/bin/env perl 

use strict; 
use warnings; 

use Text::ParseWords 'parse_line'; 

foreach my $line (<DATA>) { 
    print join '|', parse_line(',', 1, $line); 
} 

__DATA__ 
"BOSW0001","Mr","Wayne","Boswell","Wayne,Jessica & Lyn","31 Baker St" 
"ELLI0007","Mrs","Bronwyn","Elliott","Bronwyn, Paul & Arianne","98A Dandaraga Rd" 
"KENN0001","Mr","Leigh","Kenning","Leigh & Beth,Cole","22 Lake St" 
+0

感谢分享的人 – Soncire

+1

我不知道为什么这么多人到达Text :: CSV时,这个核心模块通常也完成这项工作。 –