问题
I need to get an array of all possible cases of a string. Like it's written here:
Combination of all possible cases of a string
How do I do that in Perl efficiently?
I want something like this:
print "$_\n" for GetCases('perl');
# Output:
perl
Perl
...
pERl
...
PERL
Note
I tagged glob
because it's the function to which I want to feed the result, so people as me will later find the question. However, The question is not only about this particular case of usage.
Related question : Should I insert some code when asking for idea?
回答1:
If you're aiming to use if for glob
anyway then you can use glob
's built-in pattern generation
my $filename = 'File.CSV';
my $test = $filename =~ s/([a-z])/sprintf '{%s,%s}', uc($1), lc($1)/iegr;
say $test, "\n";
say for glob $test;
output
{F,f}{I,i}{L,l}{E,e}.{C,c}{S,s}{V,v}
FILE.CSV
FILE.CSv
FILE.CsV
FILE.Csv
FILE.cSV
FILE.cSv
FILE.csV
FILE.csv
FILe.CSV
FILe.CSv
FILe.CsV
FILe.Csv
FILe.cSV
FILe.cSv
FILe.csV
FILe.csv
FIlE.CSV
FIlE.CSv
FIlE.CsV
FIlE.Csv
FIlE.cSV
FIlE.cSv
FIlE.csV
FIlE.csv
FIle.CSV
FIle.CSv
FIle.CsV
FIle.Csv
FIle.cSV
FIle.cSv
FIle.csV
FIle.csv
FiLE.CSV
FiLE.CSv
FiLE.CsV
FiLE.Csv
FiLE.cSV
FiLE.cSv
FiLE.csV
FiLE.csv
FiLe.CSV
FiLe.CSv
FiLe.CsV
FiLe.Csv
FiLe.cSV
FiLe.cSv
FiLe.csV
FiLe.csv
FilE.CSV
FilE.CSv
FilE.CsV
FilE.Csv
FilE.cSV
FilE.cSv
FilE.csV
FilE.csv
File.CSV
File.CSv
File.CsV
File.Csv
File.cSV
File.cSv
File.csV
File.csv
fILE.CSV
fILE.CSv
fILE.CsV
fILE.Csv
fILE.cSV
fILE.cSv
fILE.csV
fILE.csv
fILe.CSV
fILe.CSv
fILe.CsV
fILe.Csv
fILe.cSV
fILe.cSv
fILe.csV
fILe.csv
fIlE.CSV
fIlE.CSv
fIlE.CsV
fIlE.Csv
fIlE.cSV
fIlE.cSv
fIlE.csV
fIlE.csv
fIle.CSV
fIle.CSv
fIle.CsV
fIle.Csv
fIle.cSV
fIle.cSv
fIle.csV
fIle.csv
fiLE.CSV
fiLE.CSv
fiLE.CsV
fiLE.Csv
fiLE.cSV
fiLE.cSv
fiLE.csV
fiLE.csv
fiLe.CSV
fiLe.CSv
fiLe.CsV
fiLe.Csv
fiLe.cSV
fiLe.cSv
fiLe.csV
fiLe.csv
filE.CSV
filE.CSv
filE.CsV
filE.Csv
filE.cSV
filE.cSv
filE.csV
filE.csv
file.CSV
file.CSv
file.CsV
file.Csv
file.cSV
file.cSv
file.csV
file.csv
回答2:
I'd be thinking in terms of:
- Loop through the number of possibilities. (2^length).
- Print the 'count' in binary, because that gives a bit mask.
- Use that bit mask to flip the bits on each iteration.
Something like this:
#!/usr/bin/env perl
use strict;
use warnings;
my $string = "abcde";
for my $mask ( 0 .. 2**length($string) - 1 ) {
my @bits = split( '', sprintf( "%0" . length($string) . "b\n", $mask ) );
for ( split( '', $string ) ) {
if ( shift @bits ) {tr/a-z/A-Z/}
print;
}
print "\n";
}
This works on pure alphabetical strings to the transformations, but it will always generated 2^length strings, and any character that isn't alphabetic will create duplicates.
'abcdef' will generate case variants to 'abcdeF, abcdEf, abcdEF...ABCDEF'. However '12345678' will generate 256 identical strings.
The easiest way of dealing with that case if it's problematic is to use a hash of strings rather than an array, and use keys
to extract the uniques.
However, as you note in your comments:
I need case-insensitive glob to find all files in folders with no matter to cases. As I couldn't get glob working case-insensitively, I thought that feeding it all possible cases of a string is the best way out. To my mind, there's no better language that Perl to cope with such things, but I don't know how to do it without monkeycode.
What you want is to be looking at File::Glob - specifically the :nocase
parameter.
来源:https://stackoverflow.com/questions/31474164/perl-get-array-of-all-possible-cases-of-a-string