我有一个包含这样的元素的数组:
@ORF= (MEZQFVECQWSXC*FVCXRCT*, MAEZCRTDRX*AZEFZC*AZERC*)
我想拆分每个数组,以便每个元素以'M'
开头,以'*'
结尾,中间没有额外的'*'
。
所以我上面的例子应该给我
@ORF = (MEZQFVECQWSXC*,MAEZCRTDRX*)
我想过要先拆分这样的每个元素:
foreach (@ORF) {
my $true= split /\*/, $_;
push @ORF, $true
}
然后使用if语句拼接其他人,但这不起作用。
我还考虑过使用grep
@ORF= grep m/M.*\*/, @ORF;
但这不会影响阵列。
我越来越困惑,谷歌没有帮助......请帮帮我?
答案 0 :(得分:3)
您确实可以使用split
和循环执行此操作。您也可以使用map
代替for
循环。
use strict;
use warnings;
use Data::Printer;
my @ORF= ('MEZQFVECQWSXC*FVCXRCT*', 'MAEZCRTDRX*AZEFZC*AZERC*');
@ORF = map { (split /\*/, $_, 0 )[0] . '*' } @ORF;
p @ORF;
它会遍历@ORF
上的split
和*
中的每个元素。 0
作为thrid参数告诉split
仅拆分一次。将返回值视为一个列表,只取第一个元素([0]
),放回星号,你就得到了一个以M
开头的新字符串列表,最后以星号。
[
[0] "MEZQFVECQWSXC*",
[1] "MAEZCRTDRX*"
]
当然,假设只有符合此模式的字符串而不进行检查。
更简单的方法是使用substr
和index
来查找*
的第一次出现,并将字符串的开头直到该字符。这可能更像你想对splice
做的事情,但却误解了它的作用。
@ORF = map { substr $_, 0 , index($_, '*') + 1 } @ORF;
答案 1 :(得分:2)
foreach (@ORF) { my $true= split /\*/, $_; push @ORF, $true }
这实际上非常接近解决方案。只有几个问题。
首先,您将split
的返回值分配给标量变量。在标量上下文中,split
返回它可以将字符串分成的项目数,而不是项目本身。因此,您只需获得值2.我们可以通过将其作为列表分配来解决这个问题。
my ($true) = split /\*/, $_;
其次,您将push
新值@ORF
发送到@ORF
的末尾。这意味着$_
只会越来越长,你的循环永远不会结束。您需要使用新值替换数组的当前元素。您可以通过分配到foreach (@ORF) {
my ($true) = split /\*/, $_;
$_ = "$true*";
}
来完成此操作。
所以整个循环变成:
15 % 7 = 1
21 % 7 = 0
5 % 7 = 5
说了这么多,我更喜欢simbabque' map
solution。
答案 2 :(得分:0)
如果你愿意,你也可以使用map + grep,如下所示:
use Data::Dumper;
my @ORF= ("MEZQFVECQWSXC*FVCXRCT*", "MAEZCRTDRX*AZEFZC*AZERC*");
@ORF = grep { $_ =~ /^M/ } map { (split/\*/, $_)[0] . '*' } @ORF;
print Data::Dumper->Dump(\@ORF);
结果:
$VAR1 = 'MEZQFVECQWSXC*';
$VAR2 = 'MAEZCRTDRX*';