UPDATE:
根据讨论结果这个问题,取决于您对构成“不使用循环”的意图/标准,map
基于下面的解决方案(参见“选项1)可能是最简洁的解决方案,前提是您不考虑map
一个循环(答案的简短版本是:就实现/性能而言,这是一个循环,从语言理论的角度来看,它不是一个循环)。
假设您不关心答案是“3”还是“Sony”,在简单的情况下,您可以通过构建具有“或”逻辑的正则表达式(|
) 来自数组,如下所示:
my @strings = ("Canon", "HP", "Sony");
my $search_in = "Sony's Cyber-shot DSC-S600";
my $combined_search = join("|",@strings);
my @which_found = ($search_in =~ /($combined_search)/);
print "$which_found[0]\n";
我的测试运行结果:Sony
正则表达式将(一旦变量$combined_search
由 Perl 插入)采用以下形式/(Canon|HP|Sony)/
这就是你想要的。
如果任何字符串包含正则表达式特殊字符(例如|
or )
) - 在这种情况下你需要逃避他们
NOTE: 我个人认为这有点作弊,因为为了实现join()
,Perl 本身必须在解释器内的某处执行循环。因此,这个答案可能无法满足您保持无循环的愿望,具体取决于您是否出于性能考虑而想要避免循环,或者拥有更干净或更短的代码。
附:要获得“3”而不是“Sony”,您必须使用循环 - 或者以明显的方式,通过在所有循环下面进行 1 次匹配;或者通过使用一个库来避免您自己编写循环,但会在调用下面有一个循环。
我将提供 3 个替代解决方案。
#1选项:- 我最喜欢的。使用“map”,我个人仍然认为它是一个循环:
my @strings = ("Canon", "HP", "Sony");
my $search_in = "Sony's Cyber-shot DSC-S600";
my $combined_search = join("|",@strings);
my @which_found = ($search_in =~ /($combined_search)/);
print "$which_found[0]\n";
die "Not found" unless @which_found;
my $strings_index = 0;
my %strings_indexes = map {$_ => $strings_index++} @strings;
my $index = 1 + $strings_indexes{ $which_found[0] };
# Need to add 1 since arrays in Perl are zero-index-started and you want "3"
#2 选项:使用隐藏在一个不错的 CPAN 库方法后面的循环:
use List::MoreUtils qw(firstidx);
my @strings = ("Canon", "HP", "Sony");
my $search_in = "Sony's Cyber-shot DSC-S600";
my $combined_search = join("|",@strings);
my @which_found = ($search_in =~ /($combined_search)/);
die "Not Found!"; unless @which_found;
print "$which_found[0]\n";
my $index_of_found = 1 + firstidx { $_ eq $which_found[0] } @strings;
# Need to add 1 since arrays in Perl are zero-index-started and you want "3"
#3选项:这是明显的循环方式:
my $found_index = -1;
my @strings = ("Canon", "HP", "Sony");
my $search_in = "Sony's Cyber-shot DSC-S600";
foreach my $index (0..$#strings) {
next if $search_in !~ /$strings[$index]/;
$found_index = $index;
last; # quit the loop early, which is why I didn't use "map" here
}
# Check $found_index against -1; and if you want "3" instead of "2" add 1.