转换字符在字符串中的位置以考虑 "gaps"(即字符串中的非字母数字字符)

Convert the position of a character in a string to account for "gaps" (i.e., non alphanumeric characters in the string)

一言以蔽之

我有一个看起来像这样的字符串...

---MNTSDSEEDACNERTALVQSESPSLPSYTRQTDPQHGTTEPKRAGHT--------LARGGVAAPRERD

我有一个位置列表和相应的字符,看起来像这样...

position     character
10           A
12           N
53           V 
54           A

此 position/character 键不考虑字符串中的连字符 (-)。因此,例如,在给定的字符串中,第一个字母 M 在位置 1,N 在位置 2,T 在位置 3,等等。第二个连字符块之前的 T 是位置 47,连字符块之后的 L是位置48.

我需要转换位置和相应字符的列表,以便位置占连字符。像这样...

position     character
13           A
15           N
64           V 
65           A

我认为应该有一个足够简单的方法来做到这一点,但我是新手所以我可能遗漏了一些明显的东西,对此感到抱歉!我这样做是作为更大脚本的一部分,所以如果有人有办法使用 perl 来完成这个,那将是惊人的。非常感谢您,如果我可以澄清任何问题或提供更多信息,请告诉我!


我试过的

首先,我取了一个等于位置值的字符子串,计算该子串中连字符的数量,并将连字符数添加到原始位置。因此,对于我列表中的第一个 position/character,取前 10 个字符,然后该子字符串中有 3 个连字符,因此 10+3 = 13 给出了正确的位置。这适用于我的大部分职位,但当原始职位落在一堆连字符内时失败,例如职位 53 和 54。

我也试过通过去掉连字符然后像这样使用原始位置值来抓取字符...

my @array = ($string =~ /\w/g);
my $character = $array[$position];

效果很好,但后来我很难用它来转换位置以包含连字符,因为有太多匹配字符无法匹配我在这里抓取的字符回到带有连字符的原始字符串并找到其中的位置(从一开始就尝试这可能是一件愚蠢的事情)。

实际字符似乎不相关。计算非连字符就足够了:

use strict;
use warnings;
use Data::Dumper;
my $s = '---MNTSDSEEDACNERTALVQSESPSLPSYTRQTDPQHGTTEPKRAGHT--------LARGGVAAPRERD';
my @positions = (10,12,53,54);
my @transformed = ();
my $start = 0;

for my $loc(@positions){
    my $dist = $loc - $start;
    while ($dist){
        $dist-- if($s =~ m/[^-]/g);
    }
    my $pos = pos($s);
    push @transformed, $pos;
    $start = $loc;
}
print Dumper \@transformed;

打印:

$VAR1 = [
          13,
          15,
          64,
          65
        ];