如何检查字符串是否包含Perl中数组中的元素

时间:2017-07-09 12:40:29

标签: perl

我想检查字符串$ name是否以$ end array_ref

中的任何元素结尾
my $end=['.a[bc', '.de[f', '.xy]z'];
my $name="test.a[bc";

# But this is not working:
if(grep{$name=~m/\Q.+$_$/} @{$end}) { print "Yes\n"; } else {print "No\n"; } # prints "No"

4 个答案:

答案 0 :(得分:3)

问题是\Q转义(因此字面上匹配).+$(除$_的内容外)。

修正:

grep { $name =~ /\Q$_\E\z/ } @{$end}
  • 您根本不需要.+部分。
  • \E将转义限制为$_
  • \z将匹配锚定到字符串的末尾($也允许在字符串结尾之前使用\n

答案 1 :(得分:2)

请允许我在不使用正则表达式的情况下提供替代解决方案。由于问题是将字符串与子字符串进行比较,因此可以使用substr()函数:

my $end = ['.a[bc', '.de[f', '.xy]z'];
my $name= "test.a[bc" ;
my $found = grep { (substr($name, length($name) - length($_)) eq $_) } @$end;
print $found ? "Yes\n": "No\n";

这是假设length($name) >= length($_)。实际上,substr的行为也可以让我们简单地传递一个负偏移量(第二个参数):

my $found = grep { (substr($name, -length($_)) eq $_) } @$end;

这里需要注意的一点是,substr()通常不会产生任何错误和警告,仍会执行某些操作 - 因为它需要正偏移值和负偏移值。 (查看perldoc of substr(命令:perldoc -f substr)了解更多详情。)

你可以避免那些惊喜"通过添加一个预先条件来保护这个看似微不足道的假设:

my $found = grep {
    (length($name) > length($_)) &&
    (substr($name, -length($_)) eq $_)
} @$end;

这是有道理的:如果$_中的内容长于$name,则根据定义它不能是$name的后缀。

答案 2 :(得分:0)

要使用grep(),您需要使用$endsplit()变量转换为数组。请注意,grep(/pattern/,@array)会在/pattern/的每个元素中搜索@array。由于您要搜索模式中的最后四个字符,因此我们需要先将其分开。

my $end="'.a[bc', '.de[f', '.xy]z'";
my @array = split(',',$end);
my $name="test.a[bc";
my $name_end = substr($name,-5);

if( grep( m/\Q$name_end/ , @array ) ) {
    print "Yes\n";
}
else {
    print "No\n";
} # prints "No";

另一种方法是通过循环在$end中搜索每个数组元素。然而,上述解决方案有效。让我知道您的反馈意见。

答案 3 :(得分:0)

my $end=['.a[bc', '.de[f', '.xy]z'];
my $name="test.a[bc";
my %end;
@end{@$end}=();
my $found = exists $end{($name=~/.*(\..*)/)[0]};