string 如何在 Perl 数组中搜索匹配的字符串?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2925604/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 00:45:45  来源:igfitidea点击:

How do I search a Perl array for a matching string?

perlstringsearchtext

提问by Mike

What is the smartest way of searching through an array of strings for a matching string in Perl?

在 Perl 中通过字符串数组搜索匹配字符串的最聪明方法是什么?

One caveat, I would like the search to be case-insensitive

一个警告,我希望搜索不区分大小写

so "aAa"would be in ("aaa","bbb")

所以"aAa"会在("aaa","bbb")

采纳答案by Peter Tillemans

I guess

我猜

@foo = ("aAa", "bbb");
@bar = grep(/^aaa/i, @foo);
print join ",",@bar;

would do the trick.

会做的伎俩。

回答by Ether

It depends on what you want the search to do:

这取决于您希望搜索做什么:

  • if you want to find all matches, use the built-in grep:

    my @matches = grep { /pattern/ } @list_of_strings;
    
  • if you want to find the first match, use firstin List::Util:

    use List::Util 'first';  
    my $match = first { /pattern/ } @list_of_strings;
    
  • if you want to find the count of all matches, use truein List::MoreUtils:

    use List::MoreUtils 'true';
    my $count = true { /pattern/ } @list_of_strings;
    
  • if you want to know the index of the first match, use first_indexin List::MoreUtils:

    use List::MoreUtils 'first_index'; 
    my $index = first_index { /pattern/ } @list_of_strings;
    
  • if you want to simply know if there was a match, but you don't care which element it was or its value, use anyin List::Util:

    use List::Util 1.33 'any';
    my $match_found = any { /pattern/ } @list_of_strings;
    
  • 如果要查找所有匹配项,请使用内置grep

    my @matches = grep { /pattern/ } @list_of_strings;
    
  • 如果要查找第一个匹配项,请firstList::Util 中使用

    use List::Util 'first';  
    my $match = first { /pattern/ } @list_of_strings;
    
  • 如果要查找所有匹配项计数,请trueList::MoreUtils 中使用

    use List::MoreUtils 'true';
    my $count = true { /pattern/ } @list_of_strings;
    
  • 如果您想知道第一个匹配项索引,请first_indexList::MoreUtils 中使用

    use List::MoreUtils 'first_index'; 
    my $index = first_index { /pattern/ } @list_of_strings;
    
  • 如果您只想知道是否有 match,但您不关心它是哪个元素或其值,请anyList::Util 中使用

    use List::Util 1.33 'any';
    my $match_found = any { /pattern/ } @list_of_strings;
    

All these examples do similar things at their core, but their implementations have been heavily optimized to be fast, and will be faster than any pure-perl implementation that you might write yourself with grep, mapor a for loop.

所有这些示例的核心都是类似的事情,但它们的实现已经过大量优化以提高速度,并且比您可能使用grepmapfor 循环编写的任何纯 perl 实现都快。



Note that the algorithm for doing the looping is a separate issue than performing the individual matches. To match a string case-insensitively, you can simply use the iflag in the pattern: /pattern/i. You should definitely read through perldoc perlreif you have not previously done so.

请注意,执行循环的算法与执行单个匹配是一个单独的问题。要不区分大小写地匹配字符串,您可以简单地i在模式中使用标志: /pattern/i。如果您以前没有这样做过,您绝对应该通读perldoc perlre

回答by Zaid

Perl 5.10+ contains the 'smart-match' operator ~~, which returns true if a certain element is contained in an array or hash, and false if it doesn't (see perlfaq4):

Perl 5.10+ 包含“智能匹配”运算符~~,如果某个元素包含在数组或散列中,则返回 true,否则返回 false(请参阅perlfaq4):

The nice thing is that it also supports regexes, meaning that your case-insensitive requirement can easily be taken care of:

好消息是它还支持正则表达式,这意味着您可以轻松满足不区分大小写的要求:

use strict;
use warnings;
use 5.010;

my @array  = qw/aaa bbb/;
my $wanted = 'aAa';

say "'$wanted' matches!" if /$wanted/i ~~ @array;   # Prints "'aAa' matches!"

回答by daotoad

If you will be doing manysearches of the array, ANDmatching always is defined as string equivalence, then you can normalize your data and use a hash.

如果您要对数组进行多次搜索,并且匹配始终定义为字符串等价,那么您可以规范化数据并使用散列。

my @strings = qw( aAa Bbb cCC DDD eee );

my %string_lut;

# Init via slice:
@string_lut{ map uc, @strings } = ();

# or use a for loop:
#    for my $string ( @strings ) {
#        $string_lut{ uc($string) } = undef;
#    }


#Look for a string:

my $search = 'AAa';

print "'$string' ", 
    ( exists $string_lut{ uc $string ? "IS" : "is NOT" ),
    " in the array\n";

Let me emphasize that doing a hash lookup is good if you are planning on doing many lookups on the array. Also, it will only work if matching means that $foo eq $bar, or other requirements that can be met through normalization (like case insensitivity).

让我强调一下,如果您计划在数组上进行多次查找,那么进行哈希查找是很好的。此外,它仅在匹配意味着$foo eq $bar,或可以通过规范化(例如不区分大小写)满足的其他要求时才有效。

回答by Alex Reynolds

#!/usr/bin/env perl

use strict;
use warnings;
use Data::Dumper;

my @bar = qw(aaa bbb);
my @foo = grep {/aAa/i} @bar;

print Dumper \@foo;

回答by Coke Fiend

Perl string match can also be used for a simple yes/no.

Perl 字符串匹配也可用于简单的是/否。

my @foo=("hello", "world", "foo", "bar");

if ("@foo" =~ /\bhello\b/){
    print "found";
}
else{
    print "not found";
}

回答by Gilles Maisonneuve

For just a boolean match result or for a count of occurrences, you could use:

对于布尔匹配结果或出现次数,您可以使用:

use 5.014; use strict; use warnings;
my @foo=('hello', 'world', 'foo', 'bar', 'hello world', 'HeLlo');
my $patterns=join(',',@foo);
for my $str (qw(quux world hello hEllO)) {
    my $count=map {m/^$str$/i} @foo;
    if ($count) {
        print "I found '$str' $count time(s) in '$patterns'\n";
    } else {
        print "I could not find '$str' in the pattern list\n"
    };
}

Output:

输出:

I could not find 'quux' in the pattern list
I found 'world' 1 time(s) in 'hello,world,foo,bar,hello world,HeLlo'
I found 'hello' 2 time(s) in 'hello,world,foo,bar,hello world,HeLlo'
I found 'hEllO' 2 time(s) in 'hello,world,foo,bar,hello world,HeLlo'

Does not require to usea module.
Of course it's less "expandable" and versatile as some code above.
I use this for interactive user answers to match against a predefined set of case unsensitive answers.

不需要使用模块。
当然,它不像上面的一些代码那样“可扩展”和通用。
我将它用于交互式用户答案,以匹配一组预定义的不区分大小写的答案。