Как я могу хранить записи регулярных выражений в массиве в Perl?


Я пытаюсь использовать регулярное выражение в Perl. Мне было интересно, можно ли хранить все совпадения с выражением в массиве? Я знаю, что могу использовать следующее:(,...,$n) = m/expr/g; но кажется, что это может быть использовано только в том случае, если вы знаете количество совпадений, которые вы ищете. Я пробовал my @array = m/expr/g; но это, кажется, не работает.

Спасибо за вашу помощь!

4 60

4 ответа:

если вы делаете глобальный матч (/g) тогда регулярное выражение в контексте списка вернет все захваченные совпадения. Просто сделайте:

my @matches = ( $str =~ /pa(tt)ern/g )

эта команда например:

perl -le '@m = ( "foo12gfd2bgbg654" =~ /(\d+)/g ); print for @m'

дает на выходе:

12
2
654

иногда вам нужно получить все матчи по всему миру, например PHP preg_match_all делает. Если это ваш случай, то вы можете написать что-то типа:

# a dummy example
my $subject = 'Philip Fry Bender Rodriguez Turanga Leela';
my @matches;
push @matches, [, ] while $subject =~ /(\w+) (\w+)/g;

use Data::Dumper;
print Dumper(\@matches);

печати

$VAR1 = [
          [
            'Philip',
            'Fry'
          ],
          [
            'Bender',
            'Rodriguez'
          ],
          [
            'Turanga',
            'Leela'
          ]
        ];

смотрите ручную запись для perldoc perlop В разделе "сопоставление в контексте списка":

если параметр /g не используется, M / / в контексте списка возвращает список, состоящий из подвыражения, соответствующие скобкам в шаблоне, т. е., ($1 , $2 , $3 ...)

модификатор /g задает глобальное сопоставление шаблонов-то есть сопоставление столько раз, сколько возможно в пределах строки. Как он ведет себя, зависит от контекста. В контексте списка, это возвращает список подстрок, которым соответствуют любые захватывающие скобки в регулярном выражении. Если нет круглых скобок, он возвращает список всех совпадающих строк, как если бы были круглые скобки вокруг всего шаблона.

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

my @matches = ($string =~ m/word/g);

Я думаю, что это самоочевидный пример. Примечание /g модификатор в первом регулярном выражении:

$string = "one two three four";

@res = $string =~ m/(\w+)/g;
print Dumper(@res); # @res = ("one", "two", "three", "four")

@res = $string =~ m/(\w+) (\w+)/;
print Dumper(@res); # @res = ("one", "two")

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

($one, $two) = $string =~ m/(\w+) (\w+)/;