Используя чередование или класс символов для сопоставления одного символа? - PullRequest
11 голосов
/ 18 января 2011

(Примечание: заголовок, кажется, не ясен - если кто-то может перефразировать это, я все для этого!)

Учитывая это регулярное выражение: (.*_e\.txt), которое соответствует некоторым именам файлов, мне нужнодобавить некоторые другие суффиксы из одного символа в дополнение к e.Должен ли я выбрать класс персонажа или использовать чередование для этого?(Или это действительно имеет значение ??)

То есть, какой из следующих двух кажется "лучше" и почему:

a) (.*(e|f|x)\.txt) или

б) (.*[efx]\.txt)

Ответы [ 3 ]

23 голосов
/ 18 января 2011

Использование [efx] - это именно то, для чего предназначены классы символов: для соответствия одному из включенных символов. Поэтому это также самое читаемое и самое короткое решение.

Я не знаю, быстрее ли это, но я был бы очень удивлен, если бы не было. Это определенно не будет медленнее.

Мои рассуждения (даже без написания движка регулярных выражений, так что это чистая гипотеза):

Маркер регулярного выражения [abc] будет применен за один шаг механизма регулярных выражений: «Является ли следующий символ одним из a, b или c

(a|b|c) однако сообщает движку регулярных выражений

  • запомнить текущую позицию в строке для возврата, если необходимо
  • проверить, возможно ли совпадение a. Если это так, успехов. Если нет:
  • проверить, возможно ли совпадение b. Если это так, успехов. Если нет:
  • проверьте, возможно ли совпадение c. Если это так, успехов. Если нет:
  • сдавайся.
13 голосов
/ 18 января 2011

Вот эталонный тест:

обновлено согласно комментарию tchrist, разница более значительна

#!/usr/bin/perl
use strict;
use warnings;
use 5.10.1;
use Benchmark qw(:all);

my @l;
foreach(qw/b c d f g h j k l m n ñ p q r s t v w x z B C D F G H J K L M N ñ P Q R S T V W X Z/) {
    push @l, "abc$_.txt";
}

my $re1 = qr/^(.*(b|c|d|f|g|h|j|k|l|m|n|ñ|p|q|r|s|t|v|w|x|z)\.txt)$/;
my $re2 = qr/^(.*[bcdfghjklmnñpqrstvwxz]\.txt)$/;
my $cpt;

my $count = -3;
my $r = cmpthese($count, {
    'alternation' => sub {
        for(@l) {
            $cpt++ if $_ =~ $re1;
        }
    },
    'class' => sub {
        for(@l) {
            $cpt++ if $_ =~ $re2;
        }
    }
});

результат:

              Rate alternation       class
alternation 2855/s          --        -50%
class       5677/s         99%          --
1 голос
/ 18 января 2011

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

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

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