我在使用引号解析CSV数据时遇到了一些问题.我的主要问题是字段中的引号.在以下示例中,第1-4行正常工作,但5,6和7不工作.
COLLOQ_TYPE,COLLOQ_NAME,COLLOQ_CODE,XDATA
S,"BELT,FAN",003541547,
S,"BELT V,FAN",000324244,
S,SHROUD SPRING SCREW,000868265,
S,"D" REL VALVE ASSY,000771881,
S,"YBELT,"V"",000323030,
S,"YBELT,'V'",000322933,
Run Code Online (Sandbox Code Playgroud)
我想避免使用Text :: CSV,因为它没有安装在目标服务器上.意识到CSV比他们看起来更复杂我正在使用Perl Cookbook中的食谱.
sub parse_csv {
my $text = shift; #record containg CSVs
my @columns = ();
push(@columns ,$+) while $text =~ m{
# The first part groups the phrase inside quotes
"([^\"\\]*(?:\\.[^\"\\]*)*)",?
| ([^,]+),?
| ,
}gx;
push(@columns ,undef) if substr($text, -1,1) eq ',';
return @columns ; # list of vars that was comma separated.
}
Run Code Online (Sandbox Code Playgroud)
有没有人建议改进正则表达式来处理上述情况?
Ken*_*ric 34
您无法下载Text :: CSV的副本或CSV解析器的任何其他非基于XS的实现,并将其安装在您的本地目录或项目的lib/sub目录中,以便安装在与您的项目推出.
如果您无法在项目中存储文本文件,那么我想知道您是如何编写项目的.
http://novosial.org/perl/life-with-cpan/non-root/
应该是如何让这些在当地进入工作状态的良好指南.
在尝试编写自己的CSV实现之前,请考虑这一点.
Text :: CSV超过一百行代码,包括修复的bug和边缘情况,从头开始重写这些只会让你了解CSV是多么糟糕.
注意:我很难学到这一点.花了一整天的时间才能在PHP中找到一个有效的CSV解析器,之后我发现在以后的版本中添加了一个内置的解析器.这真的很可怕.
dra*_*tun 20
您可以使用Perl附带的Text :: ParseWords解析CSV .
use Text::ParseWords;
while (<DATA>) {
chomp;
my @f = quotewords ',', 0, $_;
say join ":" => @f;
}
__DATA__
COLLOQ_TYPE,COLLOQ_NAME,COLLOQ_CODE,XDATA
S,"BELT,FAN",003541547,
S,"BELT V,FAN",000324244,
S,SHROUD SPRING SCREW,000868265,
S,"D" REL VALVE ASSY,000771881,
S,"YBELT,"V"",000323030,
S,"YBELT,'V'",000322933,
Run Code Online (Sandbox Code Playgroud)
正确解析你的CSV ....
# => COLLOQ_TYPE:COLLOQ_NAME:COLLOQ_CODE:XDATA
# => S:BELT,FAN:003541547:
# => S:BELT V,FAN:000324244:
# => S:SHROUD SPRING SCREW:000868265:
# => S:D REL VALVE ASSY:000771881:
# => S:YBELT,V:000323030:
# => S:YBELT,'V':000322933:
Run Code Online (Sandbox Code Playgroud)
我使用Text :: ParseWords的唯一问题是数据中的嵌套引号未正确转义.然而,这是错误构建的CSV数据,并会导致大多数CSV解析器出现问题;-)
你可能会注意到这一点
# S,"YBELT,"V"",000323030,
Run Code Online (Sandbox Code Playgroud)
出来了(即引号下降到"V")
# S:YBELT,V:000323030:
Run Code Online (Sandbox Code Playgroud)
但是,如果它像这样逃脱
# S,"YBELT,\"V\"",000323030,
Run Code Online (Sandbox Code Playgroud)
那么报价将被保留
# S:YBELT,"V":000323030:
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
25059 次 |
| 最近记录: |