разделенный запятыми список с запятыми в кавычках в Perl - PullRequest
0 голосов
/ 25 марта 2012

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

my $string = "2, 16, \"d4,d6\", \"d20,d22\", [0]";

и я использую разделение так:

my @arglist = split(/,/, $string);

Проблема в том, что изначально у меня никогда не было этих запятых в кавычках, и теперь у меня есть, и мне нужно обновить это разделенное регулярное выражение для обработки этого случая.

Пожалуйста, , абсолютно не упоминайте ничего, кроме того, что я прошу. Я искал достаточно, и более половины ответов - это шум о том, насколько сложен синтаксический анализ CSV и т. Д. И т. Д. Я не написал тот сценарий, который мне нужно исправить, и все, что я хочу, - это изменить эту единственную строку, которая выполняет разбиение, поэтому он должен быть простым регулярным выражением, которое делает это. Там не будет никаких обновлений, и текст, который он разделяет, будет таким только:

CHROMA_MC_X \width, \align, "d4,d5,d6,d7", "d20,d21,d22,d23"
CHROMA_MC_X \width, \align, "d4,d6", "d20,d22", [0]
CHROMA_MC_X \width, \align, "d4,d6", "d20,d22", [0]




EDIT Ответа Бирея было достаточно, чтобы начать с. Я закончил готовить это регулярное выражение, которое отлично подходит для моего случая:

my @arglist = $3 =~ m/(?:(?<=")[^"]*(?=(?:\s*"\s*,|\s*"\s*$)))|(?<=,)(?:[^",]*(?=(?:\s*,|\s*$)))|(?<=^)(?:[^",]+(?=(?:\s*,|\s*$)))|(?<=^)(?:[^",]*(?=(?:\s*,)))/g;

Это выглядит грязно, но это именно то, что мне нужно. Он сопоставляет цитируемые списки с запятыми и возвращает их без кавычек, были некоторые проблемы с пустыми аргументами, которые могли присутствовать, и это регулярное выражение беспорядочно, потому что оно просто обрабатывает эти случаи и избегает этой ошибки с переменной длина, которая не реализована в регулярном выражении Perl.

Чего я не понимаю: в чем причина всех этих отрицательных голосов, я атакован некоторыми Perl-гуру, которые думают, что я не знаю, что мне нужно и чего я прошу ?! У меня есть инструмент, который выполняет некоторую предварительную обработку asm, и все, что мне нужно, это обработать несколько случаев. ВОТ И ВСЕ. Спасибо за помощь.

Ответы [ 3 ]

7 голосов
/ 25 марта 2012

В одну сторону:

Содержимое script.pl:

use warnings;
use strict;

my $string = "2, 16, \"d4,d6\", \"d20,d22\", [0]";
my @arglist = $string =~ m/("[^"]+"|[^,]+)(?:,\s*)?/g;
printf qq[%s\n], join qq[\n], @arglist;

Запустите как:

perl script.pl

со следующим результатом:

2
16
"d4,d6"
"d20,d22"
[0]
6 голосов
/ 25 марта 2012

Вы говорите, что не хотите ничего делать, кроме split, но Text :: CSV_XS прекрасно с этим справляется. Возможно, вам не нравится этот ответ по каким-либо эмоциональным причинам, которые вы приложили к проблеме, но кто-то еще может оценить это. Помните, это не сайт, который поможет вам решить вашу проблему, это сайт, который поможет всем.

use Text::CSV_XS;

my $csv = Text::CSV_XS->new(
    {
    allow_whitespace => 1,
    }
    ) or die "Cannot use CSV: ".Text::CSV_XS->error_diag;

$" = "\n";
while( my $row = $csv->getline( $filehandle ) ) {
    say "@$row\n";
    }
5 голосов
/ 25 марта 2012

Data :: Record

Иногда нам нужно разбить данные на записи и выполнить простое разбиение на разделителе входной записи ($ /) или какое-либо другое значение не удается, поскольку значениямы делимся на разрешенные в других частях данных.Возможно, они цитируются.Возможно, они встроены в другие данные, которые не следует разбивать на части.

Этот модуль позволяет вам указать, на что вы хотите разделить данные, а также указать регулярное выражение «если».Если рассматриваемый текст соответствует регулярному выражению «кроме», он не будет разбит там.Это позволяет нам делать такие вещи, как разделение на новые строки, если новые строки не заключены в кавычки.

...