Perl регулярное выражение захватывает группы без захвата - PullRequest
0 голосов
/ 08 мая 2018

Я использую Perl для анализа файла CSV. Я использую регулярное выражение, чтобы разобрать его вместо любой библиотеки. Я знаю, что есть библиотека синтаксических анализаторов CSV, и не только одна, но я просто решил, что хочу использовать REGEX.

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

Я хочу использовать красоту perl, поместив ее в одну строку:

my $text = '"",hi there,"","2018-04-23,\" 13:14:53",,hostname,mac,"ipaddress",199';

my @data = $text =~ m/(?:^|,)(?:"(|.*?[^\\])"|([^,]*))(?:|$)/g;

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

Вот код тестирования:

my $text = '"",hi there,"","2018-04-23,\" 13:14:53",,hostname,mac,"ipaddress",199';

my @data = $text =~ m/(?:^|,)(?:"(|.*?[^\\])"|([^,]*))(?:|$)/g;
foreach (@data) { print "a --${_}--\n"; }

while ($text =~ m/(?:^|,)(?:"(|.*?[^\\])"|([^,]*))(?:|$)/cg) {
    print "b --${1}${2}--\n";
}

Результаты для дампа "a":

a ----
a ----
a ----
a --hi there--
a ----
a ----
a --2018-04-23,\" 13:14:53--
a ----
a ----
a ----
a ----
a --hostname--
a ----
a --mac--
a --ipaddress--
a ----
a ----
a --199--

Вы можете увидеть дополнительные пустые строки в отличие от правильных результатов из дампа "b":

b ----
b --hi there--
b ----
b --2018-04-23,\" 13:14:53--
b ----
b --hostname--
b --mac--
b --ipaddress--
b --199--

Кто-нибудь сталкивался с этой проблемой? Спасибо за ваши ответы / идеи / выводы об ошибках.

1 Ответ

0 голосов
/ 08 мая 2018

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

Виновным является этот раздел регулярного выражения:

(?:"(|.*?[^\\])"|([^,]*))

Все прошло хорошо после замены группы без захвата на сброс ветви функция:

(?|"(|.*?[^\\])"|([^,]*))

Итак, окончательная рабочая правильная однострочная:

my @data = $text =~ m/(?:^|,)(?|"(|.*?[^\\])"|([^,]*))(?:|$)/g;

Надеюсь, кто-то найдет эту информацию полезной.

...