Arrays 如何在Perl中将整个字符串拆分为数组
我试图处理整个字符串,但按照我编写代码的方式,部分字符串没有被处理。以下是我的代码的表示:Arrays 如何在Perl中将整个字符串拆分为数组,arrays,string,perl,Arrays,String,Perl,我试图处理整个字符串,但按照我编写代码的方式,部分字符串没有被处理。以下是我的代码的表示: #!/usr/bin/perl my $string = "MAGRSHPGPLRPLLPLLVVAACVLPGAGGTCPERALERREEEAN VVLTGTVEEILNVDPVQHTYSCKVRVWRYLKGKDLVARESLLDGGNKVVISGFGDPLI CDNQVSTGDTRIFFVNPAPPYLWPAHKNELMLNSSLMRITLR
#!/usr/bin/perl
my $string = "MAGRSHPGPLRPLLPLLVVAACVLPGAGGTCPERALERREEEAN
VVLTGTVEEILNVDPVQHTYSCKVRVWRYLKGKDLVARESLLDGGNKVVISGFGDPLI
CDNQVSTGDTRIFFVNPAPPYLWPAHKNELMLNSSLMRITLRNLEEVEFCVEDKPGTH
LRDVVVGRHPLHLLEDAVTKPELRPCPTP";
$string =~ s/\s+//g; # remove white space from string
# split the string into fragments of 58 characters and store in array
my @array = $string =~ /[A-Z]{58}/g;
my $len = scalar @array;
print $len . "\n"; # this prints 3
# print the fragments
print $array[0] . "\n";
print $array[1] . "\n";
print $array[2] . "\n";
print $array[3] . "\n";
代码输出以下内容:
3
MAGRSHPGPLRPLLPLLVVAACVLPGAGGTCPERALERREEEANVVLTGTVEEILNVD
PVQHTYSCKVRVWRYLKGKDLVARESLLDGGNKVVISGFGDPLICDNQVSTGDTRIFF
VNPAPPYLWPAHKNELMLNSSLMRITLRNLEEVEFCVEDKPGTHLRDVVVGRHPLHLL
<blank space>
3
MAGRSHPPLRPLLPLLVVAACVLPGGTCPERLEEANVLTGTVEEILLNVD
PVQHTYSCKVRVWRYLKKKDLVARESLLDGGNKVVISGDGPLICDNQVSTGDTRIFF
vnpappylwpahknelmlnsslritlrnlevefcvedkpgthlrdvvvgrhplhll
请注意,字符串的其余部分
EDAVTKPELRPCPTP
未存储在@array
中。创建阵列时,如何存储EDAVTKPELRPCPTP
?也许我可以将其存储在$array[3]
?中,您缺少的是捕获少于58个字符的能力。既然你只想在结束时这样做,你可以这样做:
/[A-Z]{58}|[A-Z]{1,57}\z/
我更愿意这样写:
/\p{Upper}{58}|\p{Upper}{1,57}\z/
但是,由于此表达式在默认情况下是贪婪的,因此它更喜欢收集58个字符,并且在匹配的输入用完时,默认值为更少
/\p{Upper}{1,58}/
或者,出于Schwern提到的原因(例如避免任何外国信件)
你几乎成功了。您需要更改正则表达式以允许1到58个字符
my @array = $string =~ /[A-Z]{1,58}/g;
此外,在脚本中使用
@prot_seq
而不是@array
时出现错误。你应该总是使用严格的来保护自己不受这种事情的伤害。下面是包含严格、警告和5.10功能(要获取)的脚本
如果您实际上不需要正则表达式字符类,我会这样做:
use strict;
use warnings;
use Data::Dump;
my $string = "MAGRSHPGPLRPLLPLLVVAACVLPGAGGTCPERALERREEEAN
VVLTGTVEEILNVDPVQHTYSCKVRVWRYLKGKDLVARESLLDGGNKVVISGFGDPLI
CDNQVSTGDTRIFFVNPAPPYLWPAHKNELMLNSSLMRITLRNLEEVEFCVEDKPGTH
LRDVVVGRHPLHLLEDAVTKPELRPCPTP";
$string =~ s/\s+//g;
my @chunks;
while (length($string)) {
push(@chunks, substr($string, 0, 58, ''));
}
dd($string, \@chunks);
输出:
(
"",
[
"MAGRSHPGPLRPLLPLLVVAACVLPGAGGTCPERALERREEEANVVLTGTVEEILNVD",
"PVQHTYSCKVRVWRYLKGKDLVARESLLDGGNKVVISGFGDPLICDNQVSTGDTRIFF",
"VNPAPPYLWPAHKNELMLNSSLMRITLRNLEEVEFCVEDKPGTHLRDVVVGRHPLHLL",
"EDAVTKPELRPCPTP",
],
)
您可能更喜欢使用
解包
,如下所示
$string =~ s/\s+//g;
my @fragments = unpack '(A58)*', $string;
或者,如果您希望保持$string
不变,并使用5.14或更高版本的Perl,那么您可以编写
my @fragments = unpack '(A58)*', $string =~ s/\s+//gr;
在这种情况下,我建议不要使用POSIX字符类。当您解析语言并希望确保正确国际化时,它们非常有用。但是,编码可能是特定的ASCII字符A到Z。您不想选择像¨或¨E这样的东西。@Schwern:这些不是POSIX字符类,它们是Unicodeproperties@Borodin技术上正确!不要在这里使用它们中的任何一个。@Schwern:虽然我不确定
\p{Upper}
和\p{Lu}
之间的区别。值得注意的是,Perl5.14及更高版本具有/a
修改器,因此/\p{Lu}/a
与/[a-Z]/
相同;我不确定我是谁prefer@Borodin我更愿意看到非常简单的[A-Z]
而不是去查找\p{Lu}
和/A
所做的事情,并且需要5.14/a
很高兴知道。请不要将变量命名为@array
。@
表示它是一个数组;这些字母被认为是为了传达一些有用的内容。这个答案假设数据完全由A-Z
组成。这也是破坏性的。考虑到示例输入和原始问题已经在修改$string
,我认为这两个假设都是有效的。
$string =~ s/\s+//g;
my @fragments = unpack '(A58)*', $string;
my @fragments = unpack '(A58)*', $string =~ s/\s+//gr;