Как разделить строку на массив запятыми, но игнорировать запятые в двойных кавычках? - PullRequest
0 голосов
/ 13 февраля 2011

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

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

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

print $array[2];

Дает

soccer,baseball,hockey

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

Ответы [ 7 ]

11 голосов
/ 13 февраля 2011

Просто используйте 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;
}
7 голосов
/ 13 февраля 2011

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

my @array = parse_line(q{,}, 0, $string);
4 голосов
/ 13 февраля 2011

В ответ на то, как это сделать с помощью 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 source в файл с именем CSV_PP.pm в папке с именем Text, созданной в том же каталоге, что и ваш скрипт. Вы также можете поместить его в другое место и использовать метод use lib 'directory', как обсуждалось ранее. См. здесь и здесь , чтобы увидеть другие способы обойти ограничение установки с использованием модулей CPAN.

0 голосов
/ 04 октября 2016

попробуйте

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

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

0 голосов
/ 19 октября 2015

Используйте это регулярное выражение: 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"
0 голосов
/ 13 февраля 2011

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

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

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

$ "=" \ n ";

print "$ array [2]";

0 голосов
/ 13 февраля 2011
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'
#        ];
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...