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;