Как разделить строку на массив запятыми, но игнорировать запятые в двойных кавычках?
У меня есть строка:
$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]";