【发布时间】:2011-06-26 08:02:52
【问题描述】:
我有一条线:
$string = 'Paul,12,"soccer,baseball,hockey",white';
我尝试将其拆分为具有 4 个值的 @array
print $array[2];
给
足球,棒球,曲棍球我该怎么做?救命!
【问题讨论】:
我有一条线:
$string = 'Paul,12,"soccer,baseball,hockey",white';
我尝试将其拆分为具有 4 个值的 @array
print $array[2];
给
足球,棒球,曲棍球我该怎么做?救命!
【问题讨论】:
只需使用Text::CSV。从the source 可以看出,正确解析 CSV 是相当复杂的:
sub _make_regexp_split_column {
my ($esc, $quot, $sep) = @_;
if ( $quot eq '' ) {
return qr/([^\Q$sep\E]*)\Q$sep\E/s;
}
qr/(
\Q$quot\E
[^\Q$quot$esc\E]*(?:\Q$esc\E[\Q$quot$esc\E0][^\Q$quot$esc\E]*)*
\Q$quot\E
| # or
[^\Q$sep\E]*
)
\Q$sep\E
/xs;
}
【讨论】:
use lib "directory" 结构,请参阅 perldoc.perl.org/lib.html .
use strict;
use warning;
#use Data::Dumper;
my $string = qq/Paul,12,"soccer,baseball,hockey",white/;
#split string into three parts
my ($st1, $st2, $st3) = split(/,"|",/, $string);
#output: st1:Paul,12 st2:soccer,baseball,hockey st3:white
#split $st1 into two parts
my ($st4, $st5) = split(/,/,$st1);
#push records into array
push (my @test,$st4, $st5,$st2, $st3 ) ;
#print Dumper \@test;
print "$test[2]\n";
输出:
soccer,baseball,hockey
#$VAR1 = [
# 'Paul',
# '12',
# 'soccer,baseball,hockey',
# 'white'
# ];
【讨论】:
Data::Dumper 仅用于将数组显示为人类可读的形式。
Data::Dumper是用来以Perl可读的形式展示一个Perl结构的。
$string = "Paul,12,\"soccer,baseball,hockey\",white";
1 while($string =~ s#"(.?),(.?)"#\"$1aaa$2\"#g);
@array = map {$_ =~ s/aaa/ /g; $_ =~ s/\"//g; $_} 拆分(/,/, $string);
$" = "\n";
打印“$array[2]”;
【讨论】:
标准模块Text::ParseWords 也会这样做。
my @array = parse_line(q{,}, 0, $string);
【讨论】:
parse_line,但首先我会使用 $string =~ s|'|\'|g;,其效果比预期的要好得多!
响应如何使用 Text::CSV(_PP)。这是一个快速的。
#!/usr/bin/perl
use strict;
use warnings;
use Text::CSV_PP;
my $parser = Text::CSV_PP->new();
my $string = "Paul,12,\"soccer,baseball,hockey\",white";
$parser->parse($string);
my @fields = $parser->fields();
print "$_\n" for @fields;
通常会通过cpan 实用程序安装Text::CSV 或Text::CSV_PP。
为了解决您无法安装模块的问题,我建议您使用“纯 Perl”实现,以便您可以“安装”它。假设您将 Text::CSV_PP 源的文本复制到名为 CSV_PP.pm 的文件中,则上述示例将起作用,该文件位于与您的脚本在同一目录中创建的名为 Text 的文件夹中。您也可以将它放在其他位置并使用前面讨论的use lib 'directory' 方法。请参阅 here 和 here 了解使用 CPAN 模块绕过安装限制的其他方法。
【讨论】:
使用这个正则表达式:m/("[^"]+"|[^,]+)(?:,\s*)?/g;
上述正则表达式全局匹配任何以逗号或引号开头的单词,然后根据起始字符(逗号或引号)匹配剩余的单词。
这是一个示例代码和相应的输出。
my $string = "Word1, Word2, \"Commas, inbetween\", Word3, \"Word4Quoted\", \"Again, commas, inbetween\"";
my @arglist = $string =~ m/("[^"]+"|[^,]+)(?:,\s*)?/g;
map { print $_ , "\n"} @arglist;
这是输出:
Word1
Word2
"Commas, inbetween"
Word3
"Word4Quoted"
"Again, commas, inbetween"
【讨论】:
试试这个
@array=($string =~ /^([^,]*)[,]([^,]*)[,]["]([^"]*)["][,]([^']*)$/);
该数组将包含您期望的输出。
【讨论】: