如何通过逗号将字符串拆分为数组但忽略双引号内的逗号?

时间:2011-02-13 05:07:45

标签: regex arrays perl csv

我有一句话:

$string = 'Paul,12,"soccer,baseball,hockey",white';

我尝试将其拆分为具有4个值的@array

print $array[2];

给予

soccer,baseball,hockey

我是怎么做到的?救命啊!

7 个答案:

答案 0 :(得分:11)

只需使用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;
}

答案 1 :(得分:7)

标准模块Text::ParseWords也会这样做。

my @array = parse_line(q{,}, 0, $string);

答案 2 :(得分:4)

回应如何使用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;

通常会通过Text::CSV实用程序安装Text::CSV_PPcpan

要解决您无法安装模块的问题,我建议您使用'纯Perl'实现,以便您可以'安装'它。假设您将Text::CSV_PP源文本复制到名为CSV_PP.pm的文件夹中,并在与脚本相同的目录中创建的文件夹Text中复制了上述示例。您也可以将其放在其他位置并使用前面讨论的use lib 'directory'方法。请参阅herehere,了解使用CPAN模块解决安装限制的其他方法。

答案 3 :(得分:0)

使用此正则表达式: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"

答案 4 :(得分:0)

试试这个

  @array=($string =~ /^([^,]*)[,]([^,]*)[,]["]([^"]*)["][,]([^']*)$/);

数组将包含您期望的输出。

答案 5 :(得分:-1)

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'
#        ];

答案 6 :(得分:-1)

$ string =“保罗,12岁,”足球,棒球,曲棍球“,”白色“;

1 while($ string =〜s#“(。?),(。?)”#\“$ 1aaa $ 2 \”#g);

@array = map {$ _ = ~s / aaa / / g; $ _ = ~s / \“// g; $ _} split(/,/,$ string);

$“=”\ n“;

print“$ array [2]”;