regex 如何从Perl数组中选择某些元素?

wz3gfoph  于 2023-11-20  发布在  Perl
关注(0)|答案(6)|浏览(99)

我想搜索一个数组中的所有元素,这些元素与另一个数组中的元素具有相同的起始字符集。为了清楚起见:

@array = ("1a","9","3c");
@temp =("1","2","3");

字符串
我只想打印1a和3c。当我尝试使用下面的程序时,它打印出数组中的所有元素,而不是我想要的两个:

foreach $word (@temp)
{
    if( grep /^$word/ , @array) 
    {
        print $_;
    }
}

a8jjtwal

a8jjtwal1#

这个答案将做OP想要的事情,并通过使用哈希查找来防止任何重复打印在屏幕上。

#!/usr/bin/perl

use strict;
use warnings;

my @array = ("1a","9","3c","3c");
my @temp =("1","2","3");

my %dups_hash;

for my $w (@temp) {
    my ($match) = grep /^$w/, @array;

    # Need to check if $match is defined before doing the hash lookup.
    # This suppresses error messages for uninitialized values; if defined($match) is
    #  false, we short circuit and continue in the loop.
    if(defined($match) && !defined($dups_hash{$match})) {
        print $match;
    }
}

字符串

vxqlmq5t

vxqlmq5t2#

如果你想两两匹配,你可以这样做:

for my $i (0..$#array) {
    print $array[$i], "\n" if $array[$i] =~ /^$temp[$i]/
}

字符串
你可以使用grep:

for my $i (0..$#array) {
    print "$array[$i]\n" if grep /^$temp[$i]/, @array;
}

w46czmvw

w46czmvw3#

对于这类问题,诀窍是不要扫描数组超过你必须。我想Knuth写了一本关于这一点的书。:)通常,我们陷入这些情况是因为我们太接近我们首先尝试的东西。
您可以从所有要搜索的模式中构造一个正则表达式,然后扫描数组一次:

use Regexp::Assemble;

my @array = qw( 1a 9 3c );
my @temp  = qw( 1 2 3 );

my $ra = Regexp::Assemble->new;
$ra->add( @temp );

my $pattern = $ra->re;
print "pattern is [$pattern]\n";

print join ' ', grep /\A$pattern/ , @array;

字符串
当您不关心模式的哪个部分匹配时,只要它匹配,这种方法就可以工作。

tyg4sfes

tyg4sfes4#

当我尝试使用下面的程序时,它会打印出数组中的所有元素,而不是我想要的两个。
不,它不会。正如所写的那样,它不打印任何内容。如果打开strict,它会打印“全局符号“$temp”需要显式包”。
修复了这个明显的拼写错误并打开了警告,它打印了两次“在打印中使用未初始化的值$_”。
你的问题的解决方案是这样的:

#!/usr/bin/perl

use strict;
use warnings;

my @array = ("1a","9","3c");
my @temp =("1","2","3");

foreach my $word (@temp) {
  print grep /^$word/ , @array;
}

字符串
但可能还有更有效的方法。

1aaf6o9v

1aaf6o9v5#

map { print "$_\n" } grep { my $a = $_; grep {$a =~ /^$_/} @temp } @array

字符串
基本上,外部grep选择@temp中的一个或多个元素与内部正则表达式匹配的元素-也就是说,它选择以@temp中的一个(或多个)元素开始的所有元素。

col17t5w

col17t5w6#

为了避免grep返回空列表时出现空行:

#!/usr/bin/perl
use strict;
use warnings;
use 5.10.1;

my @array = qw(1a 9 3c 1g);
my @temp =(1, 2, 3);
foreach my $word(@temp) {
  my @l = grep{/^$word/}@array;
  say "@l" if @l;
}

字符串
输出量:

1a 1g
3c

相关问题