Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/opencv/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Arrays 用正则表达式Perl搜索数组_Arrays_Regex_Perl - Fatal编程技术网

Arrays 用正则表达式Perl搜索数组

Arrays 用正则表达式Perl搜索数组,arrays,regex,perl,Arrays,Regex,Perl,这将返回0,3,1,这是@array中$search词的索引。索引不会识别$search4,因为它是正则表达式。 我的问题是,如何使用正则表达式搜索@array?qw用于引用单词列表,要将正则表达式存储在变量中,最好使用: 获取单个任意匹配索引: my $search4 = qr/_/; # the leading and trailing '.*?' are redundant 或全部: my ($index4) = grep $array[$_] =~ /$search4/, 0..$#

这将返回0,3,1,这是@array中$search词的索引。索引不会识别$search4,因为它是正则表达式。
我的问题是,如何使用正则表达式搜索@array?

qw
用于引用单词列表,要将正则表达式存储在变量中,最好使用:

获取单个任意匹配索引:

my $search4 = qr/_/; # the leading and trailing '.*?' are redundant 
或全部:

my ($index4) = grep $array[$_] =~ /$search4/, 0..$#array; 

在您的代码中有一个不相关的问题,
$search4
不是一个reqex。
$search4=~qw/*?*./
表示您正在将未定义的变量
$search4
qw/*?。*?/
qw
基本上是在空白处拆分字符串。在本例中,没有空格,因此您要与字符串
*?551;.*?
进行匹配。在void上下文中,这一点都不起作用,
$search4
未定义

严格使用;使用警告并且在声明变量之后,您会得到一个适当的错误

my @i = grep $array[$_] =~ /$search4/, 0..$#array;
我想你的意思是
$search4=qr/*?*?/

解决问题的一个方法是将regexp作为一个特例处理,并在数组上循环

$ cat t1.pl 
use strict;
use warnings;

my @array = ('Joe','Jim','Jim_BOB','Hello');
my $search = "Joe";
my $search2 = "Hello";
my $search3 = "Jim";
my $search4 =~ qw/.*?_.*?/;

my %index;
@index{@array} = (0..$#array);
my $index = $index{$search};
my $index2 = $index{$search2};
my $index3 = $index{$search3};
my $index4 = $index{$search4};
print $index,",",$index2,",",$index3,",",$index4, "\n";

$ perl t.pl 
Use of uninitialized value $search4 in pattern match (m//) at t.pl line 8.
Use of uninitialized value $search4 in hash element at t.pl line 15.
Use of uninitialized value $index4 in print at t.pl line 16.
0,3,1,
如果您想使用查找哈希,那么您可能会喜欢来自CPAN的模块

$ cat t2.pl 
use strict;
use warnings;

my @array = ('Joe','Jim','Jim_BOB','Hello');
my $search = 'Joe';
my $search2 = 'Hello';
my $search3 = 'Jim';
my $search4 = qr/.*?_.*?/;

my %index;
@index{@array} = (0..$#array);
my $index = $index{$search};
my $index2 = $index{$search2};
my $index3 = $index{$search3};

# loop over the array until a match is found
my $cnt = 0;
my $index4;
for my $elem ( @array ) {
    if ( $elem =~ $search4 ) {
        $index4 = $cnt;
        last;
    }
    $cnt++;
}

print "$index,$index2,$index3,$index4\n";

$ perl t2.pl 
0,3,1,2

请注意,这种解决方案有一些缺点。如果多个密钥匹配,则无法保证将获得匹配的密钥中的哪一个。如果传递的字符串看起来不像regexp,它仍将被视为regexp。

如果数组包含重复元素,则当前使用哈希的方法将只返回最后一个匹配的索引。其他答案显示了如何修复现有代码,但为了允许重复元素,可以使用

下面显示了如何获取固定搜索字符串和正则表达式的第一个和最后一个匹配索引,以及如何获取所有匹配索引:

$ cat t3.pl 
use strict;
use warnings;

# modules from CPAN
use Tie::Hash::Regex;

my @array = ('Joe','Jim','Jim_BOB','Hello');
my $search = "Joe";
my $search2 = "Hello";
my $search3 = "Jim";
my $search4 = qr/.*?_.*?/;

my %index;
tie %index, 'Tie::Hash::Regex';
@index{@array} = (0..$#array);
my $index = $index{$search};
my $index2 = $index{$search2};
my $index3 = $index{$search3};
my $index4 = $index{$search4};
print "$index,$index2,$index3,$index4\n";
bernhard@bernhard-Aspire-E1-572:~/devel/StackOverflow$ perl t3.pl 
0,3,1,2
输出:
第一个吉姆:1
最后吉姆:6
吉姆:1,4,6
第一个正则表达式:0
最后正则表达式:6
所有正则表达式:0、1、2、4、6

旁注:
qw
使用空格作为分隔符,将字符串拆分为单词列表。可能不是你想要的。此外,您的正则表达式可以简化为
/\u/
(即在字符串中的任何位置包含下划线)。此外,请注意,由于哈希不能包含重复的键,因此在重复数组元素的情况下,此技术只会为您提供最后一个匹配索引。例如,如果您的数组是
my@array=qw(foo-bar-baz-foo)
,那么
$index{foo}
将是3,最后一个
foo
的索引?重点是搜索
@array
。(
%index
只是用来查找O(N+M)而不是O(N*M)中的精确字符串的机制。)为了获得第一个匹配项,可以使用
List::Util::first()
。在精确情况下使用%index速度更快,但如果这是一个问题,则必须考虑构造成本。它可能同样有效/^$search1$|^$search2$| ^$search3$|$search4/@Ben Grimm如何使用正则表达式使变量区分大小写?@JDE876我想你是想在Ben Grimm的答案上发布这个,但是。。。默认情况下,正则表达式已经区分大小写。如果要使它们不区分大小写,可以使用
i
标志,例如
'FoO'=~/FoO/i
$ cat t3.pl 
use strict;
use warnings;

# modules from CPAN
use Tie::Hash::Regex;

my @array = ('Joe','Jim','Jim_BOB','Hello');
my $search = "Joe";
my $search2 = "Hello";
my $search3 = "Jim";
my $search4 = qr/.*?_.*?/;

my %index;
tie %index, 'Tie::Hash::Regex';
@index{@array} = (0..$#array);
my $index = $index{$search};
my $index2 = $index{$search2};
my $index3 = $index{$search3};
my $index4 = $index{$search4};
print "$index,$index2,$index3,$index4\n";
bernhard@bernhard-Aspire-E1-572:~/devel/StackOverflow$ perl t3.pl 
0,3,1,2
use strict;
use warnings;
use 5.010;

use List::MoreUtils qw(first_index last_index indexes);

my @words = qw(Joe Jim Jim_BOB Hello Jim Hello Jim);

my $string = 'Jim';
my $regex = '^J';

say "First $string: " . first_index { $_ eq $string } @words;
say "Last $string: " . last_index { $_ eq $string } @words;
say "All $string: " . join ', ', indexes { $_ eq $string } @words;

say "First regex: " . first_index { /$regex/ } @words;
say "Last regex: " . last_index { /$regex/ } @words;
say "All regex: " . join ', ', indexes { /$regex/ } @words;