Perl:获取字符串所有可能情况的数组

Perl : Get array of all possible cases of a string

我需要获取字符串所有可能情况的数组。就像这里写的那样:

Combination of all possible cases of a string

如何在 Perl 中高效地做到这一点?

我想要这样的东西:

print "$_\n" for GetCases('perl');

# Output:
perl
Perl
...
pERl
...
PERL

备注

我标记了 glob 因为这是我要将结果提供给的函数,所以像我这样的人稍后会找到问题。然而,问题不仅仅在于这种特殊的用法。

相关问题:Should I insert some code when asking for idea?

如果您打算为 glob 使用 if,那么您可以使用 glob 的内置模式生成

my $filename = 'File.CSV';

my $test = $filename =~ s/([a-z])/sprintf '{%s,%s}', uc(), lc()/iegr;

say $test, "\n";
say for glob $test;

输出

{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^长度).
  • 以二进制形式打印 'count',因为这给出了一个位掩码。
  • 使用该位掩码在每次迭代中翻转位。

像这样:

#!/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";
}

这适用于转换的纯字母字符串,但它总是会生成 2^length 字符串,并且任何 不是 字母的字符都会创建重复项。

'abcdef' 将生成 'abcdeF, abcdEf, abcdEF...ABCDEF' 的大小写变体。但是 '12345678' 将生成 256 个相同的字符串。

如果有问题,处理这种情况的最简单方法是使用字符串散列而不是数组,并使用 keys 提取唯一值。

但是,正如您在评论中指出的那样:

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.

您想要的是查看 File::Glob - 特别是 :nocase 参数。