Re: string containing characters
by GrandFather (Saint) on Jan 21, 2025 at 06:22 UTC
|
use strict;
use warnings;
my @wanted = (1, 2, 3, 4);
for my $test ('1432', '1345', 'brown fox') {
my $count = grep {$test =~ /$_/} @wanted;
if ($count == @wanted) {
print "'$test' contains all wanted characters\n";
} elsif ($count) {
print "'$test' does not contain all wanted characters\n";
} else {
print "'$test' contains no wanted characters\n";
}
}
Prints:
'1432' contains all wanted characters
'1345' does not contain all wanted characters
'brown fox' contains no wanted characters
Which contains some deliberate errors and should not be used for "production" code.
Optimising for fewest key strokes only makes sense transmitting to Pluto or beyond
| [reply] [d/l] [select] |
|
|
...
my $count = grep { -1 != index $test, $_ } @wanted;
...
map{substr$_->[0],$_->[1]||0,1}[\*||{},3],[[]],[ref qr-1,-,-1],[{}],[sub{}^*ARGV,3]
| [reply] [d/l] [select] |
|
|
| [reply] [d/l] |
|
|
| [reply] |
Re: string containing characters
by hippo (Archbishop) on Jan 21, 2025 at 09:17 UTC
|
use strict;
use warnings;
use Test::More tests => 2;
my $goodstr = 'Can you suggest code to determine whether a string cont
+ains all of a list of characters in any order?';
my $badstr = 'How to ask better questions using Test::More and sample
+data';
my @list = qw/? s a y/;
ok haschars ($goodstr, @list), 'Match';
ok !haschars ($badstr, @list), 'No match';
sub haschars {
my $str = shift;
for my $c (@_) {
return 0 if -1 == index $str, $c;
}
return 1;
}
See also How to ask better questions using Test::More and sample data.
| [reply] [d/l] |
|
|
| [reply] [d/l] |
|
|
| [reply] [d/l] |
|
|
|
|
Re: string containing characters
by tybalt89 (Monsignor) on Jan 21, 2025 at 15:17 UTC
|
#!/usr/bin/perl
use strict; # https://perlmonks.org/?node_id=11163777
use warnings;
my @wanted = (1, 2, 3, 4);
my $pattern = join '', map "(?=.*\Q$_\E)", @wanted;
for my $test ('1432', '1345', 'brown fox', '9876?54321')
{
printf "%20s => %s\n", $test,
$test =~ /^$pattern/s ? "has all" : "does not have all";
}
Outputs:
1432 => has all
1345 => does not have all
brown fox => does not have all
9876?54321 => has all
| [reply] [d/l] [select] |
|
|
Note: Possibly ok, but doesn't handle duplicates in @wanted. (Looking for two x would be done by building (?=.*x.*x).)
The advantage of this way is that you can check a large number of strings against one list efficiently (by adding my $re = /^$pattern/s and using $re in the loop).
| [reply] [d/l] [select] |
Re: string containing characters
by tybalt89 (Monsignor) on Jan 22, 2025 at 20:07 UTC
|
#!/usr/bin/perl
use strict; # https://perlmonks.org/?node_id=11163777
use warnings;
my @wanted = (1, 2, 3, 4, 2);
my $pattern = join '.*', map quotemeta, sort @wanted;
for my $test ('1432', '21432', '1345', 'brown fox', '98276?54321')
{
printf "%20s => %s\n", $test,
(join '', sort split //, $test) =~ /$pattern/s
? "has all" : "does not have all";
}
print "\n";
sub hasall # similar to what I did in https://perlmonks.org/?node_id=1
+1108516
{
my ($have, @want) = @_;
$have =~ s/\Q$_// or return 0 for @want;
return 1;
}
for my $test ('1432', '21432', '1345', 'brown fox', '98276?54321')
{
printf "%20s => %s\n", $test,
hasall( $test, @wanted ) ? "has all" : "does not have all";
}
Outputs:
1432 => does not have all
21432 => has all
1345 => does not have all
brown fox => does not have all
98276?54321 => has all
1432 => does not have all
21432 => has all
1345 => does not have all
brown fox => does not have all
98276?54321 => has all
| [reply] [d/l] [select] |
Re: string containing characters
by harangzsolt33 (Deacon) on Jan 21, 2025 at 06:38 UTC
|
I would use a regex to eliminate characters from one string that appear in another. If that one string becomes empty at the end, then we know that all the characters in it occurred in the other string. So, I use this logic to decide whether the string matches all characters or not. In the following example, the "Hello World" string contains all of these characters: o r e H
What this little program does not do is that it does not count how many letters are matched. So, if you want to know if a string contains at least 5 letter A's and 3 B's and 2 C's, then this program is not going to work...
#!/usr/bin/perl -w
use strict;
use warnings;
my $SAMPLE = "Hello World\r\n";
my $MATCHALL = "oreH";
$MATCHALL =~ s/[\Q$SAMPLE\E]+//g;
if (length($MATCHALL) == 0)
{
print "\nCONTAINS ALL THE CHARACTERS\n";
}
else
{
print "\nDOES NOT CONTAIN ALL THE CHARACTERS\n";
}
exit;
| [reply] [d/l] |
|
|
| [reply] [d/l] |
|
|
Yeah, that's true. But we could turn it around and then it works:
#!/usr/bin/perl -w
use strict;
use warnings;
my $SAMPLE = "Hello World\r\n";
my $MATCHALL = "ooreH\r\n";
my $SAMPLE_LENGTH = length($SAMPLE);
$SAMPLE =~ s/[\Q$MATCHALL\E]{1}//g;
if (length($SAMPLE) == $SAMPLE_LENGTH - length($MATCHALL))
{
print "\nCONTAINS ALL THE CHARACTERS\n";
}
else
{
print "\nDOES NOT CONTAIN ALL THE CHARACTERS\n";
}
exit;
| [reply] [d/l] |
|
|
|
|