我想检查字符串$ 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"
答案 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()
,您需要使用$end
将split()
变量转换为数组。请注意,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]};