我有2个数组列表,如果任何单词匹配,我想找到它,得到这两个值。
For examples
array1 array2
int1<->int2 int9<->int1 --->Matched as Int1 is common. Get both the values(e.g int1<->int21,int9<-
int3<->int4 int10<->int11 ->> not matched
int5<->int6 int13<->int14-->> no matched
int7<->int8 int8<->int15 -- Macthed int8 Get $var1=int7<->int8,$var2=int8<->int15
希望它有意义。请让我知道任何疑问。
答案 0 :(得分:2)
它并不完全清楚你想要什么,但也许这就是:
my @a = qw(int1<->int2 int3<->int4 int7<->int8);
my @b = qw(int9<->int1 int10<->int11 int8<->int15);
for my $i (0..$#a) {
my ($w1, $w2) = ($a[$i] =~ /([^<]+)<->(.+)/);
if (index($b[$i],$w1)!=-1 || index($b[$i],$w2)!=-1) {
print "match: $a[$i], $b[$i]\n";
}
}
说明:
有两个(并行)数组a
和b
,其中要比较重合元素。通过提取a
元素的两个子串来比较它们。每个都经过测试,以查看是否是b
元素的子字符串。如果其中一个是子字符串,则认为它是匹配的。 (index
返回子串的索引,如果不存在子串,则返回-1。)
答案 1 :(得分:1)
稍微更优雅的解决方案,将您的一个密钥转换为用于比较的列表正则表达式。因此,捕获匹配的密钥:
my @a = qw(int1<->int2 int3<->int4 int7<->int8);
my @b = qw(int9<->int1 int10<->int11 int8<->int15);
for my $i (0..$#a) {
my $list_re = join '|', map quotemeta, split '<->', $a[$i];
if ($b[$i] =~ /\b($list_re)\b/) {
print "match $1: $a[$i], $b[$i]\n";
}
}
答案 2 :(得分:0)
这比ooga采用的方法略显费力。我在这里说一个不太流畅的 Perl 版本:-)
脚本将数据分成数组并通过匹配和保存子模式=~ /()...()/
并将它们存储为变量(与ooga的方法几乎相同)来创建两个模式。然后我使用第二个正则表达式遍历其中一个匹配每个元素的数组与另一个数组的元素。对于更复杂的字符串,不均匀分布的数据或更大的设置数据,我不确定foreach
if..elsif
逻辑是否可能会遗漏某些内容。然而,作为一个快速测试,我将下面的脚本与ooga的工作进行了比较,他们给出了相同的输出; - )
智能匹配(~~
),match::simple
或match::smart
可能适用于较新版本的 Perl 。
#!/usr/bin/env perl
use strict;
use warnings;
my (@col1, @col2);
while (<DATA>) {
chomp; my @data = split/ / ;
push @col1, $data[0];
push @col2, $data[1];
}
foreach my $i (0 .. $#col1 ) {
my ($patt1, $patt2) = ( $col1[$i] =~ /([^<]+)<->(.+)/ );
if ($col2[$i] =~ $patt1 ) {
print "$col1[$i] matches $col2[$i] \n";
}
elsif ($col2[$i] =~ $patt2 ) {
print "$col1[$i] matches $col2[$i] \n";
}
}
__DATA__
int1<->int2 int9<->int1
int3<->int4 int10<->int11
int5<->int6 int13<->int14
int7<->int8 int8<->int15
我不得不说我确实更喜欢ooga的基于index
的干净方法。如果我的脚本有效(即测试它)并且您喜欢传统的 Perl 正则表达式,请投票给我。
欢呼和快乐perl
- ing。