Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Regex 使用正则表达式查找一个包含五个字母abcde的单词,每个字母以任何顺序出现一次,中间不间断_Regex_Perl - Fatal编程技术网

Regex 使用正则表达式查找一个包含五个字母abcde的单词,每个字母以任何顺序出现一次,中间不间断

Regex 使用正则表达式查找一个包含五个字母abcde的单词,每个字母以任何顺序出现一次,中间不间断,regex,perl,Regex,Perl,例如,debacle一词会因为debac而起作用,但seabed不会起作用,因为:1。在任何可以形成的5个字符序列中都没有c,并且2。字母e出现两次。另一个例子是,由于edbac,反馈会起作用。请记住,解决方案必须只使用正则表达式 我尝试实施的一个策略是:匹配[A-e]中的第一个字母,并记住它。然后在[a-e]中找到下一个字母,但不要找到第一个字母。等等我不确定语法是什么(甚至不确定是否存在某些语法),因此我的代码无法工作: open(DICT, "dictionary.txt"); @word

例如,debacle一词会因为debac而起作用,但seabed不会起作用,因为:1。在任何可以形成的5个字符序列中都没有c,并且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;
}
}
open(DICT,“dictionary.txt”);
@单词=;
foreach我的$word(@words){
如果($word=~/([a-e])([a-e^\1])([a-e^\1^\2])([a-e^\1^\2^\3])([a-e^\1^\2^\3^\4]))/
){
打印$word;
}
}
我也在考虑使用(?=regex)和\G,但我不确定它会如何工作

/
   (?= .{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| abcde| ABCDC| ABCDC| abedc| abedc | acbed | acbed | ABCDC| ABCDC| ABCDCDC| ABCDCDCDCDC| ABCDCDCDCDCDC| ABADDC| abedc| ABD| acbed | acbed| acbed | acbed| acbed| acbed | acbed| acbed| acbed | acbed | ABD| ABABD| ABD| ABD| ABABD| ABD| ABCDCDCDCDCD卡德|卡德|卡德|卡德|卡德|卡德|卡德|卡德|卡德|卡德|卡德|卡德|卡德|卡德|卡德|卡德|卡德|卡德|卡德|卡德|卡德|卡德|CBAよ卡迪亚(CBA)卡迪亚(CBA)卡迪亚(CBA)卡迪亚(CBA)卡迪亚(CBA)卡迪亚(CBA)卡迪亚(CBA)卡迪亚(CBA)卡迪亚(CBA)卡迪亚(CBA)卡迪亚(CBA)卡迪亚(CBA)卡迪亚(CDB)卡迪亚(CDB(CDB)卡迪亚(CDB)卡迪亚(CDB)卡迪亚(CDB)卡迪亚,卡迪亚(CDB)卡迪亚,卡迪亚(CDB)卡迪亚(卡迪亚)卡迪亚,卡迪亚布(卡迪亚)卡迪亚)卡迪亚,卡迪亚(CDB(CDB)卡迪亚,卡迪亚,卡迪亚)卡迪亚,卡迪亚,卡迪亚,卡迪亚,卡迪亚,卡迪亚,卡迪亚,卡迪亚,卡迪亚布(CDB(卡埃巴德|埃巴德|埃巴德|埃巴德|埃巴德|埃巴德|埃巴德|埃巴德|埃巴德|埃巴德|埃巴德|埃巴德|埃巴德|埃巴德|埃巴德|埃巴德|埃巴德|埃巴德|埃巴德|埃巴德|埃巴德|埃巴德||edbac | edbca | edcab | edcba


(这将在Perl 5.10+中优化为trie。在5.10之前,请使用Regexp::List。)

您的解决方案很聪明,但不幸的是,
[a-e^…]
无法工作,正如您所发现的。我不相信有一种方法可以混合常规角色类和否定角色类。不过,我可以想到一种使用lookaheads的解决方法:

    /(([a-e])(?!\2)([a-e])(?!\2)(?!\3)([a-e])(?!\2)(?!\3)(?!\4])([a-e])(?!\2)(?!\3)(?!\4])(?!\5)([a-e]))/
请看这里:

更新:Mob在下面的评论中指出,可以使用替换来压缩上述内容:

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

新的演示:。

+1-我更喜欢这个,而不是我自己的解决方案。为了向其他人解释,lookaheads保证:在接下来的5个字母中,至少有一个“a”、至少一个“b”、至少一个“c”、至少一个“d”和至少一个“e”。考虑到只有五个“槽”,可以保证每个槽只出现一次。如果您想找到具有重复(例如abcdd而不是abcde)的内容,则另一种解决方案也有效,+1请注意,在字符类中不能有反向引用。因此需要多个反向引用,而不是像
(?![\2\3\4\5])
这样的东西。此外,我必须从2开始计数,而不是1,因为我想为rubular演示包含一个“整体”捕获组。但是您可以使用替代选项:
…(!\2\3\4\5)
    /(([a-e])(?!\2)([a-e])(?!\2|\3)([a-e])(?!\2|\3|\4])([a-e])(?!\2|\3|\4|\5)([a-e]))/