Как я могу узнать, какая часть регулярного выражения Perl соответствует строке? - PullRequest
5 голосов
/ 15 июля 2011

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

что-то вроде этого:

my @regs = (qr/a/, qr/b/, qr/c/);
foreach my $line (<ARGV>) {
   foreach my $reg (@regs) {
      if ($line =~ /$reg/) {
         printf("matched %s\n", $reg);
      }
   }
}

, но это может быть медленным.

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

my $master_reg = join("|", @regs); # this is wrong syntax. what's the right way?
foreach my $line (<ARGV>) {
   $line =~ /$master_reg/;
   my $matched = special_function();
   printf("matched the %sth reg: %s\n", $matched, $regs[$matched]
}

}

, где 'special_function' - это специальный соус, сообщающий мне, с какой частью регулярного выражения было найдено соответствие.

Ответы [ 2 ]

8 голосов
/ 15 июля 2011

Используйте захватные скобки. Основная идея выглядит так:

my @matches = $foo =~ /(one)|(two)|(three)/;
defined $matches[0]
    and print "Matched 'one'\n";
defined $matches[1]
    and print "Matched 'two'\n";
defined $matches[2]
    and print "Matched 'three'\n";
5 голосов
/ 15 июля 2011

Добавить группы захвата:

"pear" =~ /(a)|(b)|(c)/;
if (defined $1) {
    print "Matched a\n";
} elsif (defined $2) {
    print "Matched b\n";
} elsif (defined $3) {
    print "Matched c\n";
} else {
    print "No match\n";
}

Очевидно, что в этом простом примере вы могли бы использовать /(a|b|c)/ точно так же и просто напечатать $1, но когда 'a', 'b' и 'c' могут быть произвольно сложными выражениями, это выигрыш.

Если вы создаете регулярное выражение программно, вам может быть неудобно использовать пронумерованные переменные, поэтому вместо нарушения строгости посмотрите вместо этого массивы @- или @+, которые содержат смещения для каждого соответствия позиция. $-[0] всегда устанавливается, если шаблон соответствует вообще, но более высокое значение $-[$n] будет содержать определенные значения, только если n -ая группа захвата соответствует.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...