匹配字符串数组以在perl中搜索的最简单方法?

Ben*_*nee 7 arrays string perl comparison search

我想要做的是检查我的搜索字符串的字符串数组并获取相应的键,以便我可以存储它.使用Perl是否有一种神奇的方法,或者我注定要使用循环?如果是这样,最有效的方法是什么?

我对Perl比较新(我只编写了2个其他脚本),所以我还不知道很多魔法,只是Perl是魔术= D

Reference Array: (1 = 'Canon', 2 = 'HP', 3 = 'Sony')
Search String: Sony's Cyber-shot DSC-S600
End Result: 3
Run Code Online (Sandbox Code Playgroud)

DVK*_*DVK 11

更新:

根据此问题中的讨论结果,根据您对"不使用循环"构成的意图/标准,map下面的基础解决方案(请参阅" 选项#1")可能是最简洁的解决方案,前提是您没有考虑map一个循环(答案的简短版本是:就实现/性能而言,它是一个循环,从语言理论的角度来看,它不是一个循环).


假设你不关心你是否得到"3"或"索尼"作为答案,你可以在一个简单的情况下通过|从数组中使用"或"logic()构建一个正则表达式来完成它,就像这样:

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";
Run Code Online (Sandbox Code Playgroud)

我的测试运行结果: Sony

正则表达式(一旦变量$combined_search由Perl插值)将采用/(Canon|HP|Sony)/您想要的形式.

如果任何字符串包含正则表达式特殊字符(例如|)),这将无法正常工作 - 在这种情况下,您需要转义它们

注意:我个人认为这有点作弊,因为为了实现join(),Perl本身必须在interpeter内的某个地方做一个循环.因此,这个答案可能无法满足您保持无环路的愿望,这取决于您是想避免出现性能考虑的循环,还是要使代码更清晰或更短.


PS要获得"3"而不是"索尼",你将不得不使用一个循环 - 要么以明显的方式,通过在它下面的循环中进行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"
Run Code Online (Sandbox Code Playgroud)

#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"
Run Code Online (Sandbox Code Playgroud)

#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.
Run Code Online (Sandbox Code Playgroud)