Как разделить строку на массив запятыми, но игнорировать запятые в двойных кавычках?

У меня есть строка:

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

Я пытаюсь разделить это на @array, который имеет 4 значения так

print $array[2];

дает

футбол, бейсбол, хоккей

Как мне это? Помогите!

7 ответов

Решение

В ответ на то, как это сделать с помощью 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_PP сквозь cpan полезность.

Чтобы обойти вашу неспособность установить модули, я предлагаю вам использовать "чистую Perl" реализацию, чтобы вы могли "установить" ее. Приведенный выше пример будет работать, если вы скопировали текст источника Text:: CSV_PP в файл с именем CSV_PP.pm в папке с именем Text создан в той же директории, что и ваш скрипт. Вы также можете поместить его в другое место и использовать use lib 'directory' метод, как обсуждалось ранее. Смотрите здесь и здесь, чтобы увидеть другие способы обойти ограничение установки с использованием модулей CPAN.

Просто используйте Text:: CSV. Как видно из источника, правильно разобрать 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;
}

Стандартный модуль Text::ParseWords также сделает это.

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

Используйте это регулярное выражение: 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 =~ /^([^,]*)[,]([^,]*)[,]["]([^"]*)["][,]([^']*)$/);

массив будет содержать ожидаемый вами вывод.

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

$string = "Пол,12 лет,\" футбол, бейсбол, хоккей \", белый";

1 while ($ string = ~ s # "(.?), (.?)" # \ "$ 1aaa $ 2 \" # g);

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

$ "=" \ n ";

print "$ array [2]";

Другие вопросы по тегам