Используя регулярные выражения для поиска слова с пятью буквами abcde, каждая буква появляется ровно один раз, в любом порядке, без перерывов между ними - программирование
Подтвердить что ты не робот

Используя регулярные выражения для поиска слова с пятью буквами abcde, каждая буква появляется ровно один раз, в любом порядке, без перерывов между ними

Например, слово debacle будет работать из-за debac, но морское дно не будет работать, потому что: 1. не существует c в любой 5-символьной последовательности, которая может быть сформирована, и 2. буква e появляется дважды. В качестве другого примера обратная связь будет работать из-за edbac. И помните, что решение должно быть выполнено с использованием только регулярных выражений.

Стратегия, которую я попытался реализовать, заключалась в следующем: соответствие первой букве, если она находится внутри [a-e], и ​​запомнить ее. Затем найдите следующую букву в [a-e], но не первую букву. И так далее. Я не был уверен, что такое синтаксис (или даже если какой-то синтаксис существует), поэтому мой код не работал:

open(DICT, "dictionary.txt");
@words = <DICT>;

foreach my $word(@words){

if ($word =~ /([a-e])([a-e^\1])([a-e^\1^\2])([a-e^\1^\2^\3])([a-e^\1^\2^\3^\4])/
){
    print $word;
}
}

Я также думал об использовании (? = regex) и \G, но я не был уверен, как это сработает.

4b9b3361

Ответ 1

/
   (?= .{0,4}a )
   (?= .{0,4}b )
   (?= .{0,4}c )
   (?= .{0,4}d )
   (?= .{0,4}e )
/xs

Вероятно, это приводит к более быстрому сопоставлению для создания шаблона из всех комбинаций.

use Algorithm::Loops qw( NextPermute );
my @pats;
my @chars = 'a'..'e';
do { push @pats, quotemeta join '', @chars; } while NextPermute(@chars);
my $re = join '|', @pats;

ABCDE | abced | abdce | abdec | abecd | abedc | acbde | acbed | acdbe | acdeb | acebd | acedb | adbce | adbec | adcbe | adceb | adebc | adecb | aebcd | aebdc | aecbd | aecdb | aedbc | aedcb | bacde | baced | badce | badec | baecd | baedc | bcade | bcaed | bcdae | bcdea | bcead | bceda | bdace | bdaec | bdcae | bdcea | bdeac | bdeca | beacd | beadc | becad | becda | bedac | bedca | cabde | cabed | cadbe | cadeb | caebd | caedb | cbade | cbaed | cbdae | cbdea | cbead | cbeda | cdabe | cdaeb | cdbae | cdbea | cdeab | cdeba | ceabd | ceadb | cebad | cebda | ЦБДО | cedba | dabce | dabec | dacbe | daceb | daebc | daecb | dbace | dbaec | dbcae | dbcea | dbeac | dbeca | dcabe | dcaeb | dcbae | dcbea | dceab | dceba | deabc | deacb | debac | debca | decab | decba | eabcd | eabdc | eacbd | eacdb | eadbc | eadcb | ebacd | ebadc | ebcad | ebcda | ebdac | ebdca | ecabd | ecadb | ecbad | ecbda | ecdab | ecdba | edabc | edacb | edbac | edbca | edcab | edcba

(Это будет оптимизировано в trie в Perl 5.10+. До 5.10 используйте Regexp:: List.)

Ответ 2

Ваше решение умное, но, к сожалению, [a-e^...] не работает, как вы нашли. Я не верю, что есть способ смешать обычные и отрицательные классы символов. Я могу подумать об обходном пути, используя lookaheads:

    /(([a-e])(?!\2)([a-e])(?!\2)(?!\3)([a-e])(?!\2)(?!\3)(?!\4])([a-e])(?!\2)(?!\3)(?!\4])(?!\5)([a-e]))/

Смотрите здесь: http://rubular.com/r/6pFrJe78b6.

ОБНОВЛЕНИЕ: Моб указывает в комментариях ниже, что чередование может быть использовано для уплотнения приведенного выше:

    /(([a-e])(?!\2)([a-e])(?!\2|\3)([a-e])(?!\2|\3|\4])([a-e])(?!\2|\3|\4|\5)([a-e]))/

Новое демо: http://rubular.com/r/UUS7mrz6Ze.

Ответ 3

#! perl -lw
for (qw(debacle seabed feedback)) {
    print if /([a-e])(?!\1)
        ([a-e])(?!\1)(?!\2)
        ([a-e])(?!\1)(?!\2)(?!\3)
        ([a-e])(?!\1)(?!\2)(?!\3)(?!\4)
        ([a-e])/x;
}