【问题标题】:Change the character length of single line strings using regex使用正则表达式更改单行字符串的字符长度
【发布时间】:2014-10-17 19:24:22
【问题描述】:

我从一个 genbank 文件中提取了一个序列,该文件由具有 60 个碱基的单行字符串组成(末尾有一个 \n)。如何使用 perl 修改序列,以便使用 regex 而不是 bioperl 为每行打印 120 个碱基。 原始格式:

    1 agatggcggc gctgaggggt cttgggggct ctaggccggc cacctactgg tttgcagcgg
   61 agacgacgca tggggcctgc gcaataggag tacgctgcct gggaggcgtg actagaagcg
  121 gaagtagttg tgggcgcctt tgcaaccgcc tgggacgccg ccgagtggtc tgtgcaggtt
  181 cgcgggtcgc tggcgggggt cgtgagggag tgcgccggga gcggagatat ggagggagat
  241 ggttcagacc cagagcctcc agatgccggg gaggacagca agtccgagaa tggggagaat
  301 gcgcccatct actgcatctg ccgcaaaccg gacatcaact gcttcatgat cgggtgtgac
  361 aactgcaatg agtggttcca tggggactgc atccggatca ctgagaagat ggccaaggcc
  421 atccgggagt ggtactgtcg ggagtgcaga gagaaagacc ccaagctaga gattcgctat
  481 cggcacaaga agtcacggga gcgggatggc aatgagcggg acagcagtga gccccgggat 

我只设法将它们变成长度为 60 个字符的字符串。仍在试图弄清楚如何使它们长 120 个字符。

my @lines= <$FH_IN>;
foreach my $line (@lines) {
    if ($line=~ m/(^\s*\d+\s)[acgt]{10}\s/) {
            $line=~ s/$1//;
            $line=~ s/ //g;
            print $line;
    }

}

输入示例:

agatggcggcgctgaggggtcttgggggctctaggccggccacctactggtttgcagcgg
agacgacgcatggggcctgcgcaataggagtacgctgcctgggaggcgtgactagaagcg
gaagtagttgtgggcgcctttgcaaccgcctgggacgccgccgagtggtctgtgcaggtt
cgcgggtcgctggcgggggtcgtgagggagtgcgccgggagcggagatatggagggagat
ggttcagacccagagcctccagatgccggggaggacagcaagtccgagaatggggagaat
gcgcccatctactgcatctgccgcaaaccggacatcaactgcttcatgatcgggtgtgac
aactgcaatgagtggttccatggggactgcatccggatcactgagaagatggccaaggcc
atccgggagtggtactgtcgggagtgcagagagaaagaccccaagctagagattcgctat

每个单行字符串有 60 个碱基。

更新(仍然没有给出 120 个碱基长的 seq 行):

my @seq_60;
foreach my $line (@lines) {
        if ($line=~ m/(^\s*\d+\s)[acgt]{10}\s/) {
                $line=~ s/$1//;
                $line=~ s/ //g;
                push (@seq_60, $line);
        }
}

my @output;
for (my $pos= 0; $pos< @seq_60; $pos+= 2) {
        push (@output, $seq_60[$pos] . $seq_60[$pos+1]);
}

print @output;

【问题讨论】:

  • 一些输入预期输出会有帮助!!!!
  • 如何编写代码来做到这一点
  • 它是正则表达式。您使用的是哪种语言?
  • 我用的是perl

标签: regex perl bioinformatics genbank


【解决方案1】:

怎么样:

s/(^|\n)([^\n]{60})\n/$1$2/g

实际操作:

use strict;
use warnings;
use 5.014;

my $str = q/agatggcggcgctgaggggtcttgggggctctaggccggccacctactggtttgcagcgg
agacgacgcatggggcctgcgcaataggagtacgctgcctgggaggcgtgactagaagcg
gaagtagttgtgggcgcctttgcaaccgcctgggacgccgccgagtggtctgtgcaggtt
cgcgggtcgctggcgggggtcgtgagggagtgcgccgggagcggagatatggagggagat
ggttcagacccagagcctccagatgccggggaggacagcaagtccgagaatggggagaat
gcgcccatctactgcatctgccgcaaaccggacatcaactgcttcatgatcgggtgtgac
aactgcaatgagtggttccatggggactgcatccggatcactgagaagatggccaaggcc
atccgggagtggtactgtcgggagtgcagagagaaagaccccaagctagagattcgctat/;

$str =~ s/(^|\n)([^\n]{60})\n/$1$2/g;
say $str;

输出:

agatggcggcgctgaggggtcttgggggctctaggccggccacctactggtttgcagcggagacgacgcatggggcctgcgcaataggagtacgctgcctgggaggcgtgactagaagcg
gaagtagttgtgggcgcctttgcaaccgcctgggacgccgccgagtggtctgtgcaggttcgcgggtcgctggcgggggtcgtgagggagtgcgccgggagcggagatatggagggagat
ggttcagacccagagcctccagatgccggggaggacagcaagtccgagaatggggagaatgcgcccatctactgcatctgccgcaaaccggacatcaactgcttcatgatcgggtgtgac
aactgcaatgagtggttccatggggactgcatccggatcactgagaagatggccaaggccatccgggagtggtactgtcgggagtgcagagagaaagaccccaagctagagattcgctat

说明:

(^|\n)      : group 1, start of string or line break
(           : start group 2
  [^\n]{60} : anything that is not a line break 60 times
)           : end group 2
\n          : line break

根据评论编辑:

成对连接线:

my @out;
for (my $i = 0; $i < @arr; $i += 2) {
    chomp($in[$i]);
    push @out, $in[$i] . $in[$i+1];
}

【讨论】:

  • 在我的输入中,每个单行字符串在一个数组中都有 60 个碱基。我需要将它们连接成一个字符串吗?
  • @zebra:如果您有一组线,请成对连接这些线,请参阅我的编辑。
  • 我已经根据您的建议调整了我的代码,但它仍然没有改变,只打印了 60 个字符。更新了我的问题。
【解决方案2】:

您可以同时进行行的读取和写入,并将前一行存储在一个变量中。请参阅代码 cmets 了解正在发生的事情:

my $prev;
while (<$FH_IN>) {
    next unless /\w/; # make sure the lines have some content
    # remove the line endings
    chomp;
    # chop off the first 6 characters (the base numbers) - format is 4 chars that
    # can be numbers or spaces, a digit, and a space
    $_ =~ s/^[\s\d]{4}\d\s//g;
    # remove the spaces between bases
    $_ =~ s/\s//g;
    # have we got a saved line?
    if ($prev) {
        # print out saved line and this line
        print $prev . $_ . "\n";
        # delete the saved line $prev
        $prev = '';
    }
    else {
        # if we don't have a saved line, save this line
        $prev = $_;
    }
}

【讨论】:

    猜你喜欢
    • 2016-03-03
    • 2014-10-22
    • 1970-01-01
    • 2013-06-04
    • 2010-12-09
    • 2014-05-12
    • 1970-01-01
    • 2011-12-22
    • 2011-09-26
    相关资源
    最近更新 更多