Perl - 将特殊字符转换为质量得分中的相应数值

时间:2013-11-27 19:31:09

标签: perl

我正在尝试将以下字符集转换为相应的值,以获得fasta文件附带的质量得分:

!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~

它们的值应为0-93。因此,当我输入使用这些符号的fastq文件时,我想在质量得分文件中输出每个符号的数值。

我尝试使用split //将它们放入一个数组中,然后制作一个散列,其中每个键都是符号,值是它在数组中的位置:

for (my $i = 0; $i<length(@qual); $i++) {
print "i is $i, elem is  $qual[$i]\n";
$hash{$qual[$i]} = $i;

我试过硬编码哈希:

my %hash = {"!"=>"0", "\""=>"1", "#"=>"2", "\$"=>"3"...

对于需要它们的特殊字符有和没有转义但似乎无法使其工作。 这只是输出:

.
.
.
i is 0, elem is  !
i is 1, elem is  "
i is 0, elem is  !
i is 1, elem is  "
i is 0, elem is  !
i is 1, elem is  "
" 1
Use of uninitialized value $hash{"HASH(0x100804ed0)"} in concatenation (.) or string at convert_fastq.pl line 24, <> line 40.
HASH(0x100804ed0) 
! 0

有没有人有任何想法?我很感激帮助。

3 个答案:

答案 0 :(得分:2)

或许从角色的ord中减去33来产生你想要的值会有所帮助:

use strict;
use warnings;

my $string = q{!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~};

for ( split //, $string ) {
    print "$_ = ", ord($_) - 33, "\n";
}

部分输出:

! = 0
" = 1
# = 2
$ = 3
% = 4
& = 5
' = 6
( = 7
) = 8
* = 9
+ = 10
...

这样,您不需要构建具有字符/值对的哈希,而只需使用$val = ord ($char) - 33;来获取值。

答案 1 :(得分:2)

{ ... }

类似于

do { my %anon; %anon = ( ... ); \%anon }

所以当你做到了

my %hash = { ... };

您将一个项目分配给哈希(对哈希的引用),而不是您应该分配的键值列表。 Perl用以下内容警告过你:

Reference found where even-sized list expected

(你为什么不提这个?!)

您应该使用

my %decode_map = ( ... );

例如,

my %decode_map;
{
   my $encoded = q{!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~};
   my @encoded = split //, $encoded;
   $decode_map{$encoded[$_]} = $_ for 0..$#encoded;
}

鉴于这些基本上是非空白可打印的ASCII字符,所以你可以简单地使用

my %decode_map = map { chr($_ + 0x21) => $_ } 0x21..0x7E;

这意味着您可以完全避免构建哈希,替换

my %decode_map = map { chr($_ + 0x21) => $_ } 0x21..0x7E;

die if !exists($decode_map{$c});
my $num = $decode_map{$c};

只是

die if ord($c) < 0x21 || ord($c) > 0x7E;
my $num = ord($c) - 0x21;

答案 2 :(得分:0)

从语言不可知的角度来看:使用一个包含256个条目的数组,每个ASCII字符一个。然后你可以在['!']存储0,在[''']存储1,依此类推。在解析输入时,你可以直接在该数组中查找char的索引。预先小心错误处理,你可以存储 - 1在所有无效字符中并在解析文件时检查它。