14

たとえば、debacleという単語はdebacのために機能しますが、 seabedは次の理由で機能しません。1。形成できる5文字のシーケンスにcがない、2。文字eが2回出現する。別の例として、フィードバックedbacのために機能します。また、解決策は正規表現のみを使用して実行する必要があることを忘れないでください。

私が実装しようとした戦略は、最初の文字が[ae]内にある場合はそれと一致し、それを覚えておくというものでした。次に、[ae]で次の文字を見つけますが、最初の文字は見つけません。等々。構文が何であるか(または構文が存在する場合でも)わからなかったため、コードが機能しませんでした。

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を使用することも考えていましたが、どのように機能するかわかりませんでした。

4

3 に答える 3

15
/
   (?= .{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|cedab|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|ebacd|ebcad|ebcda|ebdac|ebdca|ecabd|ecadb|ecbad|ecbda|ecdab|ecdba|edabc|edacb|edbac|edbca|edcab|edcba

(これは Perl 5.10+ でトライに最適化されます。5.10 より前では、Regexp::List を使用してください。)

于 2012-06-21T17:40:05.590 に答える
7

あなたのソリューションは賢いですが、残念ながら[a-e^...]うまくいきません。通常の文字クラスと否定された文字クラスを混在させる方法があるとは思いません。ただし、先読みを使用して回避策を考えることができます。

    /(([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 .

更新: Mob は以下のコメントで、上記を圧縮するために代替を使用できることを指摘しています。

    /(([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 .

于 2012-06-21T17:46:19.347 に答える
6
#! 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;
}
于 2012-06-21T17:44:33.273 に答える