массив соответствия шаблонов perl - PullRequest
0 голосов
/ 14 февраля 2011

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

Вот пример общего вида вещей, которые я ищу ... конечно, это не работает, поэтому я и прошу помощи. Но я надеюсь, что этого достаточно, чтобы понять мои намерения.

Пример:

my $patterns;
my $line;

my $c = 0 ;
$patterns{$c++} = "$exact" ;  # where the $ in $exact marks the beginning of line.
$patterns{$c++} = "$T?:" ;    # where the ? is the normal wildcard
$patterns{$c++} = "" ;
$patterns{$c++} = "exact" ;

open (FILE, "example.txt") || die "Unable to open file.\n";

while (my $line = <IN>) {

  my $idx = -1;
  for ($i=0; $i<$c :$i++) {
    if ($line =~ /$patterns{$i}/ ) { $idx = $i ; }
  }

  $result = $idx;  # of course this will return index of last pattern match, but that's ok
}
close(FILE);

Ответы [ 2 ]

10 голосов
/ 14 февраля 2011

Не зная точно, что вы ищете, это ваш код, преобразованный в фактический код Perl.

use warnings;
use strict;
use autodie; # open and close will now die on failure
use 5.10.1;

my @patterns = (
  qr"^exact",
  qr"^T.?:",
  "",
  "exact",
);

my $result;

open my $fh, '<', 'example.txt';

while ( my $line = <$fh> ) {
  chomp $line;
  $result = $line ~~ @patterns;
}
close($fh);
4 голосов
/ 14 февраля 2011

С другой стороны, если вы используете Perl 5.8 вместо 5.10, Regexp :: Assemble справится с этим для вас:

use strict;
use warnings;
use autodie; # open and close will now die on failure

my @patterns = (
  qr"^exact",
  qr"^T.?:",
  "",
  "exact",
);

my $ra = Regexp::Assemble->new;
$ra->add(@patterns);

my $result;

open my $fh, '<', 'example.txt';

while ( my $line = <$fh> ) {
  chomp $line;
  $result = $ra->match($line);
}
close($fh);

R :: A также может быть установлен, чтобы сказать вам, какой из исходных шаблонов совпал, что я не думаю, может сделать оператор умного сопоставления 5.10 (~~), но это даст Вы фактический образец (exact), а не его индекс (3). Если вам действительно нужен индекс, вам нужно либо циклически пройтись по шаблонам, каждый из которых тестируется по порядку (что может иметь значительное влияние на производительность, если у вас много шаблонов), либо создать хэш pattern => index и использовать его для поиска Индекс сопоставленного шаблона.

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