2015-04-18 2 views
-1

Мне нужно найти последнее вхождение совпадений на основе массива приемлемого значения. Ниже приведены исходные коды в Perl. Ответ Q, потому что это последнее событие, основанное на допустимых значениях A, Q, I & J.Улучшение производительности последнего совпадения в Perl Regex

Задача состоит в том, как изменить мои коды, чтобы сделать регулярное выражение быстрее. В настоящее время это узкое место, потому что я должен запускать его миллионы раз.

my $input = "A B C D E F G H I J K L M N O P Q R S T U V W X Y Z"; 
my $regex = qr/(A|Q|I|J)/; 

my @matches = $input =~ m/\b$regex\b/g; 

print $matches[$#matches]; 

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

+0

'$ матчей [$ # спички]' обычно пишется '$ соответствует [-1]' – Borodin

+0

дополнительная информация: "А", можно быть словом в реальной ситуации. –

ответ

-1

Используйте \K, чтобы отбросить ранее согласованные символы от печати в финале.

my $input = "A B C D E F G H I J K L M N O P Q R S T U V W X Y Z"; 
my $regex = qr/.*\K\b[AQIJ]\b/; 
if ($input =~ m/$regex/) { 
print $&."\n"; 
} 

Используйте группу захвата.

my $input = "A B C D E F G H I J K L M N O P Q R S T U V W X Y Z"; 
my $regex = qr/.*\b([AQIJ])\b/; 
if ($input =~ m/$regex/) { 
print $1."\n"; 
} 

Update:

my $input = "Apple Orange Mango Apple"; 
my $regex = qr/.*\K\b(?:Apple|Range|Mango)\b/; 
if ($input =~ m/$regex/) { 
print $&."\n"; 
} 
+0

A может быть словом APPLE. Как мы можем изменить $ regex? –

+0

@MichaelC. то вам нужно использовать группу, не связанную с захватом, например '(?: Apple | Orange | .....)' вместо '[AQIJ]' –

+0

Не могли бы вы подтвердить, что новый код верен? Похоже, что это соответствует первому Apple (начало строки), а не последнему Apple (конец строки). –

3

Вы можете найти последний матч, просто добавив .* до соответствующего шаблона.

Как это

my $input = "APPLE B C D E F G H INDIGO JACKAL K L M N O P QUIVER R S T U V W X Y Z"; 
my $regex = qr/APPLE|QUIVER|INDIGO|JACKAL/; 
my ($last) = $input =~ /.*\b($regex)\b/; 
print $last, "\n"; 

выход

QUIVER 
+0

Для достижения контрольных целей для завершения первоначального сценария с использованием этого предлагаемого решения требуется 2 часа 04 минут. –