Perl: регулярное выражение для вырезания слов, заключенных в круглые скобки

#regex #perl

#регулярное выражение #perl

Вопрос:

У меня есть массив @WIALOG_lines с записями ниже

 (0552) -*--@  "<No comment>" 27-Oct-2020 10:40 AM
(0553) M---$ user1 100900 "Random job
(0554) ----@  1119996 "patch content"
(0562) -*--@  "<No comment>" 24-Oct-2020 10:40 AM
  

Мне нужно иметь 0552,0553,0554 и 0562 в этом массиве. Я пробую приведенную ниже команду и не работает. Можете ли вы помочь с регулярным выражением, чтобы получить значения, заключенные только в круглые скобки.

  s/(^[^(] ")|("[^)] )//g for @WIALOG_lines;
  

Комментарии:

1. Что вы пробовали? С какой проблемой вы столкнулись?

2. Обновил вопрос тем, что я пробовал

Ответ №1:

Мы хотим сопоставить числа между первым набором круглых скобок. Этот шаблон представляет собой открытую пару, любое количество символов, которые не являются закрывающей парой, и конечную пару. И мы хотим захватить символы между круглыми скобками. Круглые скобки являются особыми в регулярных выражениях, поэтому их нужно экранировать. Этот шаблон регулярного выражения: m/(([^)]*))/ , где экранированные круглые скобки совпадают буквально, а другая пара круглых скобок представляет собой группу захвата.

Затем мы хотим применить этот шаблон к каждой строке исходного массива, что предполагает использование блока карты. Для каждого элемента исходного массива выполните сопоставление и верните соответствующую часть. $1 будет строка, которая соответствует первой группе захвата.

 my @key = map { m/(([^)] ))/; $1 } @WIALOG_lines;

  

Комментарии:

1. @Ras Вы читаете файл построчно или переводите файл в одну переменную

2. TLP, я читаю построчно. Все, что я пропустил, вставляя новые записи в @WIALOG_lines. Теперь у меня все хорошо.

3. map { m/(([^)] ))/ } достаточно хорошо. На самом деле, это лучше, потому что оно добавляет undef для строк, которые не совпадают

Ответ №2:

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

 use strict;
use warnings;
use feature 'say';

my @keys = map { $1 if /^((d ))/ } <DATA>;

say for @keys;

__DATA__
(0552) -*--@  "<No comment>" 27-Oct-2020 10:40 AM
(0553) M---$ user1 100900 "Random job
(0554) ----@  1119996 "patch content"
(0562) -*--@  "<No comment>" 24-Oct-2020 10:40 AM
  

Более интересным случаем было бы, если бы входные данные требовали некоторого дополнительного синтаксического анализа. Следующий пример демонстрирует этот подход.

ПРИМЕЧАНИЕ: входные данные для записи с меткой 0553 отсутствуют закрытие "

 use strict;
use warnings;
use feature 'say';

use Data::Dumper;

my %log;

while( <DATA> ) {
    chomp;
    my @col = /((d ))s (S )s (.*)z/;
    my $data;
    if( $col[2] =~ /(.*) (d{2}-w{3}-d{4}) (d{2}:d{2}) (w{2})z/ ) {
        $data = { comment => $1, date => $2, time => $3, AM => $4 };
    } else {
        $data = { user => $1 , label => $2, desc => $3 } if $col[2] =~ /(S ) (d ) (".*?"?)z/;
        $data = {              label => $1, desc => $2 } if $col[2] =~ /(d ) (".*?")z/;
    }
    $log{$col[0]} = { perm => $col[1], data => $data };
}

say Dumper(%log);

__DATA__
(0552) -*--@  "<No comment>" 27-Oct-2020 10:40 AM
(0553) M---$ user1 100900 "Random job
(0554) ----@  1119996 "patch content"
(0562) -*--@  "<No comment>" 24-Oct-2020 10:40 AM
  

Вывод

 $VAR1 = {
          '0562' => {
                      'perm' => '-*--@',
                      'data' => {
                                  'date' => '24-Oct-2020',
                                  'AM' => 'AM',
                                  'comment' => '"<No comment>"',
                                  'time' => '10:40'
                                }
                    },
          '0553' => {
                      'perm' => 'M---$',
                      'data' => {
                                  'desc' => '"Random job',
                                  'user' => 'user1',
                                  'label' => '100900'
                                }
                    },
          '0552' => {
                      'perm' => '-*--@',
                      'data' => {
                                  'date' => '27-Oct-2020',
                                  'time' => '10:40',
                                  'AM' => 'AM',
                                  'comment' => '"<No comment>"'
                                }
                    },
          '0554' => {
                      'data' => {
                                  'label' => '1119996',
                                  'desc' => '"patch content"'
                                },
                      'perm' => '----@'
                    }
        };