通过在Perl中匹配两个字符串中的字母位置来连接两个字符串

时间:2012-10-08 04:07:40

标签: string perl

我正在尝试编写一个Perl脚本,其中字符串在每次出现'E'时都会碎片化,并且当用户通过命令行输入'C'的位置时(比如3-8或3-8,13-18或任何如果字符串很长,逗号按照这种格式的字符串分隔'C'的这些位置,包含'C'(比如3和8位)的片段应该连接并显示在输出中。假设字符串是 “ABCDEABCDEABCDEABCDEABCDE”并且用户输入3-8然后程序oputput应为 -

ABCDEABCDE
ABCDE
ABCDE
ABCDE

我编写了一个脚本,用户通过命令行输入“C”位置,并在“E”的每个位置输入字符串,但之后我无法正确编写。请帮忙!

我到目前为止编写的代码(编辑)是:

use strict;
use warnings;

my $s = 'ABCDEABCDEABCDEABCDEABCDE';
my $i=0;
my @where;
my @array;
my @bond;
my @pos;
my @s_array;
my @s_array2;

for ($i=0; $i<=4; $i++) {
    $where[$i] = index($s,"C",$where[$i-1])+1;
    push(@array,$where[$i]);
}
print "All Positions of C: @array\n\n";
print "Enter C positions:\n";
my @join_C = <STDIN>; 

foreach (@join_C) {
    @bond = split (',',$_);
}

foreach (@bond) {
    @pos = split ('-', $_);
}
print "entered C positions:@pos\n";
print "Resulting disulfide linked peptides\n\n";
my @a = split(/E/, $s); 
my $result = join ("E,", @a);
my @final = split(/,/, $result);
foreach my $final (@final) {
    foreach my $pos(@pos) {
        my @source = split //, $final[@final];
        my $length = @source;
        for ($i=0; $i<=$length; $i++) {
            if (index($final[$i], "C") == $pos[$i]) {
                push (@s_array, $final[$i]);
            }
            else {
                push (@s_array2, $final[$i]);
            }
        }
    }
}
my $lastly_joined = join (',', @s_array);
print "Joined Fragments= @s_array\n";
print "Remaining fragments= @s_array2\n";

1 个答案:

答案 0 :(得分:0)

我会尽力了解你想做什么。

  

我正在尝试编写一个Perl脚本,其中每个字符串都会被分段   发生'E'

好的,首先创建输入。让我们使用一个数组来访问 元素更容易。

my @s = split ('', 'ABCDE' x 5);

我不确定你的情况下该字符串的外观如何。你能提供一个吗? 现实世界的例子。

  

当用户通过命令行输入'C'的c_pos时(比如3-8   或3-8,13-18或任何逗号分隔这样的'C'的c_pos根据   如果字符串很长,则采用这种格式的字符串

我建议使用命令行参数。这样可以更容易地使用 稍后与其他工具链接的脚本。将参数传递给脚本:

  

script.pl 3-8,13-18

所以我们得到一对配对列表:

my @pairs = split (',', join('', @ARGV));

现在你应该检查传递的值是否指向'C'。有效组合 存储在散列中,其中键是起始索引,值是结束 指数。

my %c_pos; 
foreach my $pair (@pairs) {
   my ($from, $to) = split('-', $pair);
   if (($string[$from-1] eq 'C') && ($string[$to-1] eq 'C')) {
      $c_pos{$from-1} = $to-1;
   } else {
      warn "position ${from}-${to} not valid => ignored!\n";
   }
}
  

应该连接包含'C'(例如3和8位)的片段   并显示在输出中。

现在我们可以迭代@s的元素。当我们点击一​​个开始索引    'connecion'启动,此连接处于活动状态,直到结束    到达。

我们将所有值存储到当前条目。

当我们点击'E'并且我们不在'连接'时,当前条目是    推到我们的结果,我们从下一个空条目开始。

for (my $i=0; $i<@string; $i++) {

   if ($c_pos{$i}) {
       $inside_connection = 1;
       $end = $c_pos{$i}; 
   } elsif ($i == $end) {
       $inside_connection = 0;
       $end = 0;
   }

   $entry.=$string[$i];

   if ($inside_connection) {
      # do not split on 'E'
   } elsif ($string[$i] eq 'E') {
      # split on 'E'
      push @result, $entry;
      $entry = '';
   }
} 

因为我不知道更好,我认为像chaind连接一样    3-8,8-13将导致它像你所说的那样工作3-13。希望    适合。这是完整的脚本:

use strict;
use warnings;

my @string = split ('', 'ABCDE' x 5);       

my @pairs = split (',', join('', @ARGV));   

my %c_pos; 
foreach my $pair (@pairs) {
   my ($from, $to) = split('-', $pair);
   if (($string[$from-1] eq 'C') && ($string[$to-1] eq 'C')) {
      $c_pos{$from-1} = $to-1;
   } else {
      warn "position ${from}-${to} not valid => ignored!\n";
   }
}

my @result;
my $entry = '';
my $inside_connection = 0;
my $end=0;

for (my $i=0; $i<@string; $i++) {

   if ($c_pos{$i}) {
       $inside_connection = 1;
       $end = $c_pos{$i}; 
   } elsif ($i == $end) {
       $inside_connection = 0;
       $end = 0;
   }

   $entry.=$string[$i];

   if ($inside_connection) {
      # do not split on 'E'
   } elsif ($string[$i] eq 'E') {
      # split on 'E'
      push @result, $entry;
      $entry = '';
   }
} 

print join ("\n", @result);