I wrote the code below to cheat on Wordle (I am not good at it). Is there a way of combining the following part into single regex statement:
($word =~ m/c/i) and
($word =~ m/a/i) and
($word =~ m/o/i)
That is to find the words containing all three letters 'c','a','o', in any order.
#!/usr/bin/perl
use 5.30.3;
use warnings;
my $dic_file = "/usr/share/dict/web2";
open (IN,"<", $dic_file) or die "Cannot open file.\n $!";
while (my $word=<IN>){
chomp $word;
if (length($word) == 5){
if( ($word !~ m/[rtn]/i) and
($word =~ m/c/i) and
($word =~ m/a/i) and
($word =~ m/o/i)
){
say $word;
}
}
}
CodePudding user response:
You can get great gains by using $_
instead of $word
.
my $dic_file = "/usr/share/dict/web2";
open( my $fh, "<", $dic_file )
or die( "Can't open `$dic_file`: $!\n" );
while ( <$fh> ) {
chomp;
say if length == 5 && !/[rtn]/i && /c/i && /a/i && /o/i;
}
It is possible to get "and" out of regex using lookaheads.
my $dic_file = "/usr/share/dict/web2";
open( my $fh, "<", $dic_file )
or die( "Can't open `$dic_file`: $!\n" );
while ( <$fh> ) {
chomp;
say if /^(?=.*c)(?=.*a)(?=.*o)[^rtn]{5}\z/si;
}
You can easily write this as a one-liner.
perl -nle'print if /^(?=.*c)(?=.*a)(?=.*o)[^rtn]{5}\z/si' /usr/share/dict/web2