Я пытаюсь использовать regex в Perl. То, что я был удивлением, было то, если возможно сохранить все соответствия к выражению в массив? Я знаю, что могу использовать следующее: ($1,...,$n) = m/expr/g;
но кажется, как будто это может только использоваться, если Вы знаете количество соответствий, Вы ищете. Я попробовал my @array = m/expr/g;
но это, кажется, не работает.
Спасибо за помощь!
Если вы выполняете глобальное сопоставление ( / g
), то регулярное выражение в контексте списка вернет все захваченные совпадения. Просто выполните:
my @matches = ( $str =~ /pa(tt)ern/g )
Эта команда, например:
perl -le '@m = ( "foo12gfd2bgbg654" =~ /(\d+)/g ); print for @m'
Дает результат:
12
2
654
См. Ручную запись для perldoc perlop в разделе «Сопоставление в контексте списка»:
Если параметр / g не используется , m // в контексте списка возвращает список, состоящий из подвыражений, совпадающих с круглыми скобками в шаблоне, то есть ($ 1, $ 2, $ 3 ...)
Модификатор / g определяет глобальное соответствие шаблону - то есть совпадение как можно больше раз в строке. Как он себя ведет, зависит от контекста. В контексте списка он возвращает список подстрок, соответствующих любым захватывающим скобкам в регулярном выражении. Если круглых скобок нет, он возвращает список всех совпавших строк, как если бы круглые скобки были вокруг всего шаблона.
Вы можете просто получить все совпадения, назначив их массиву или иным образом выполнив оценку в контексте списка:
my @matches = ($string =~ m/word/g);
Иногда вам нужно получить все совпадения глобально, как это делает PHP preg_match_all
. Если это ваш случай, то вы можете написать что-то вроде:
# a dummy example
my $subject = 'Philip Fry Bender Rodriguez Turanga Leela';
my @matches;
push @matches, [$1, $2] while $subject =~ /(\w+) (\w+)/g;
use Data::Dumper;
print Dumper(\@matches);
It prints
$VAR1 = [
[
'Philip',
'Fry'
],
[
'Bender',
'Rodriguez'
],
[
'Turanga',
'Leela'
]
];