我有两个数组@uarts
和@txd
,看起来像这样
@uarts = qw(uart_1 uart_10 uart_3 uart_9 );
@txd = qw(PIO_uart_1 PIO_2_uart_1 PIO_uart_3 PIO_uart_10 PIO_uart_5 PIO_uart_9 PIO_uart_7);
我想只从@txd
中提取包含@uarts
的任何元素的元素。我为它编写的代码如下,但不起作用。
my @array;
for (my $i = 0 ; $i <= $#uarts ; $i++) {
@array = grep { $_ =~ /$uarts[$i]/ } (@txd);
print "@array\n";
}
答案 0 :(得分:5)
我必须诚实。我认为map
和grep
都非常烦人,因为如果你不熟悉perl - steer clear。他们并没有获得太多 - 他们看起来就像他们降低了代码的复杂性一样,但这是因为grep的循环是隐含的。所以你所做的就是让你的代码更难以理解。
另外 - 我真的不喜欢for
循环的样式 - 它的几乎在perl中总是多余的 - 在上面的例子中,是你引用的唯一元素是当前的(如果您正在访问&#39; next&#39;或之前的&#39;元素,那就不一样了)。
因此展开它:
foreach my $uart ( @uarts ) {
foreach my $PIO ( @txd ) {
if ( $PIO =~ m/$uart/ ) {
print "$PIO matches $uart\n";
}
}
}
注意:这不会进行任何类型的唯一性测试,因此如果发生多次匹配,您将获得欺骗。
哦,然后开启use strict;
和use warnings;
。你的数组声明是错误的。
my @uarts = qw ( uart_1 uart_10 uart_3 uart_9 );
my @txd = qw ( PIO_uart_1 PIO_2_uart_1 PIO_uart_3 PIO_uart_10
PIO_uart_5 PIO_uart_9PIO_uart_7
);
我也会指出 - 你已经将@array
限制在你的循环之外,这可能意味着想要保留它。但是,然后通过分配grep
的输出来破坏每次迭代。
我建议您在循环中定位@array
,或者查看push
/ pop
和shift
/ unshift
作为添加和删除的方法现有数组中的元素。
答案 1 :(得分:3)
您的代码&#34;工作&#34;就目前而言。你应该总是说出你的意思&#34;不工作&#34; 。
我认为问题在于您的代码正如您所描述的那样完全。它找到&#34;来自@txd
的那些元素,其中包含@uarts
&#34; 的任何元素,而我认为您需要那些结束的元素 @uarts
中的任何字符串。
因为它代表了你的节目输出
PIO_uart_1 PIO_2_uart_1 PIO_uart_10
PIO_uart_10
PIO_uart_3
PIO_uart_9
所以在检查uart_1
时,它会找到PIO_uart_10
,因为前者是后者的子串。要使用给定的uart字符串查找 end 的元素,您只需要向正则表达式添加行结束锚点,使其成为
@array = grep { $_ =~ /$uarts[$i]$/ } (@txd)
将输出更改为
PIO_uart_1 PIO_2_uart_1
PIO_uart_10
PIO_uart_3
PIO_uart_9
我希望你想要的是什么?
但它可以写得更好一点。除非你特别需要索引,否则最好循环遍历数组的内容,并且@array
不需要是一个全局变量(并且它可以更好地构建一个)所以这对你有用
use strict;
use warnings;
my @uarts = qw(uart_1 uart_10 uart_3 uart_9 );
my @txd = qw(PIO_uart_1 PIO_2_uart_1 PIO_uart_3 PIO_uart_10 PIO_uart_5 PIO_uart_9 PIO_uart_7);
for my $uart ( @uarts ) {
my @matches = grep /$uart\z/, @txd;
print "@matches\n";
}
<强>输出强>
PIO_uart_1 PIO_2_uart_1
PIO_uart_10
PIO_uart_3
PIO_uart_9
答案 2 :(得分:1)
您只需将@array = grep{$_=~ /$uarts[$i]/}(@txd);
更改为push @array, grep{$_=~ /$uarts[$i]/}(@txd);
即可修复您的代码。
但是,如何做到这一点的有效和有效的方法是准备匹配的正则表达式,并在O(N+M)
而不是O(N*M)
中进行。
use strict;
use warnings;
my @uarts = qw(uart_1 uart_10 uart_3 uart_9);
my @txd
= qw(PIO_uart_1 PIO_2_uart_1 PIO_uart_3 PIO_uart_10 PIO_uart_5 PIO_uart_9 PIO_uart_7);
my @array = do {
my $re = join '|', map quotemeta, @uarts;
$re = qr/$re/;
grep /$re/, @txd;
};
print "@array\n";
答案 3 :(得分:-3)
@uarts =(uart_1,uart_10,uart_3,uart_9 );
@txd =(PIO_uart_1,PIO_2_uart_1,PIO_uart_3,PIO_uart_10,PIO_uart_5,PIO_uart_9,PIO_uart_7);
my @array;
for(my $i=0;$i<=$#uarts;$i++ )
{
@array=grep{$_=~/$uarts[$i]/}(@uarts);
print "@array\n";
}
<强>输出强>
uart_1 uart_10
uart_10
uart_3
uart_9