【问题标题】:Figure out proper match regex找出正确的匹配正则表达式
【发布时间】:2016-03-17 01:42:28
【问题描述】:

我对编程比较陌生。我目前正在学习 Perl,但遇到了一个逻辑问题,使我无法正确完成脚本。任何帮助将不胜感激!!提前感谢您提供有用的见解!

大部分程序已经写好了,最后一步让我头疼。

我有一个变量$RNA,它以任意顺序获取核苷酸序列 (acgu)。例如:

$RNA = agcuaggaaggguuuugauag

等等。

我已经创建了一个哈希,其中每 3 个核苷酸字符或密码子(例如 uga)被分配给一个定义的氨基酸。例如:

% my AminoAcid   = (
  ggg => "G",
  ...
);

我想要做的是在读取$RNA 字符串中的START CODON aug 时打印与哈希中的密码子相对应的定义的氨基酸(大写字母)并停止 每当读取 STOP CODON uga 时,在哈希中打印定义的氨基酸。

例如:假设$RNA = aaaaugcccgggugaccccccccc。程序应打印从 (aug) 开始的相应氨基酸,并在读取字符串中的终止密码子 (uga) 时停止。

注意:它应该在读取起始密码子 (aug) 之前忽略前三个 aaa,在读取终止密码子 (uga) 之后忽略 ccccccccccccc,如果看到在字符串中的任何位置再次启动密码子aug

我尝试了多种想法,但没有一个能够描述为最后一部分编写代码的正确方法。我可能没有完全理解其背后的逻辑。

任何帮助将不胜感激。提前谢谢!!!

【问题讨论】:

  • aug 是否必须位于可被 3 整除的索引处,还是只能出现在任何地方?
  • 你能贴出你试过的代码吗?

标签: regex perl


【解决方案1】:

这可能有效,将逻辑放入代码组(?{})

多线模组
注意 - 如果需要重新对齐(按 3 个),请告诉我。
到目前为止,对齐方式是 3 个非空白 + 可选空白,重复。
这将在保持 3 个边界的同时消耗换行符 - 我
假设很重要。

Perl 代码

use strict;
use warnings;

my %AminoAcid   = (
   aug => "Start codon",
   ccc => "C",
   ggg => "G",
   uuu => "U"
);

my $RNA = '
aaaaugcccgggugacccgggcccgggcccaaaauguuugggcccugacccgggccccccaugccc
gggugacccgggcccgggcccaaaauguuugggcccugacccgggcccccc
aaaaugcccgggugacccgggcccgggcccaaaauguuugggcccugacccgggcccccc
aaaaugcccgggugacccgggcccgggcccaaaauguuugggcccugacccgggcccccc
';
my $on = 0;

$RNA =~ /
     (?:
          ( \S\S\S ) \s*
          (?{
               if ( $^N eq 'aug' ){ $on = 1; print "\n"; }
               elsif ( $^N eq 'uga' ) { $on = 0; }
               if ( $on ) {
                  exists $AminoAcid{ $^N } ?
                    print $AminoAcid{ $^N } :
                    print "[key not found-> '$^N']";
               }
          })
     )+
   /x;

输出

Start codonCG
Start codonUGC
Start codonCG
Start codonUGC
Start codonCG
Start codonUGC
Start codonCG
Start codonUGC

【讨论】:

  • 上面的代码不会打印空行。您是否复制了整个代码?是的,代码中只有一个print "\n",因为在这个块中设置了$on,所以它总是打印\n+$AminoAcid{ $^N },其中$^N是最后一个捕获缓冲区的内容,并且是该哈希值的“键”。如果该键不存在,则会使用空白值自动创建它。我会为你做一些错误检查。
  • 好的,我想我明白了,针对多行进行了调整,并为密钥存在添加了一些错误检查。
【解决方案2】:

让我们从这个开始:

my $rna = "aaaaugcccgggugaccccccccc";
my %aminoAcidMap = ( ggg => "G", ccc => "C" );

第一步,提取auguga之间的相关部分:

$rna =~ /aug((?:[acgu]{3})*?)uga/ or die;
my $pattern = $1;

这假定aug 可以出现在字符串中的任何位置。此外,如果它跨越两个密码子,它会确保 if 不会在 uga 处停止。

如果您要求起始密码子位于字符串中可被 3 整除的索引处,则可以改为:

$rna =~ /^(?:[acgu]{3})*?aug((?:[acgu]{3})*?)uga/ or die;
my $pattern = $1;

此时,$pattern 将包含auguga 之间的部分。

现在,要进行映射,您可以:

my $aminoAcids = $pattern =~ s/[acgu]{3}/$aminoAcidMap{$&}/ger;

这将用哈希值替换每个密码子。

如果你把所有东西都打包到一个 sub 中,你会得到:

sub getAminoAcids {
    local ($_) = @_;
    /aug((?:[acgu]{3})*?)uga/ or return "";
    $1 =~ s/[acgu]{3}/$aminoAcidMap{$&}/ger;
}

【讨论】:

  • 你好卢卡斯,一百万谢谢!!!!非常感谢您的帮助!我不完全遵循的唯一块是“子”块。你介意向我解释一下你到底做了什么吗?例如,哪个语句在读取 STOP 密码子时停止将密码子翻译成氨基酸?先感谢您!!另外,请原谅我的无知,是否有更简单的方法来完成同样的事情?我尝试了 for、while 和 until 循环。因为,我不是专家,所以我认为可能滥用了它们。再次感谢您!
  • @Dimitri sub 是一个子程序/函数,用于代码重用。例如:print getAminoAcids "aaaaugcccgggugaccccccccc"; 为了做到这一点,我只是从答案中提取了其他代码,去掉了临时变量并将它们放在一起。 stop 密码子由正则表达式读取(以/aug 开头的那个) - 有关更多详细信息,请参阅perlre。是的,我并没有真正选择简单易懂的方式,我选择了最紧凑、最高效的方式(用 3 行代码完成工作)。当然,Perl 并不是最容易学习的语言。
【解决方案3】:

@lucas-trzesniewski 的 sub 很棒而且非常紧凑,但它有一些缺点:它不处理散布的硬返回,只找到第一个蛋白质,不打印第一个蛋氨酸,并用隐式返回(这是我试图避免的)。所以这里有一个改进。请注意,我自己有一个非常巧妙的翻译脚本,它可以处理更多的情况(例如重叠阅读框、不明确的核苷酸、RNA 片段、替代起始密码子、多个终止密码子等),但如果你只是想要一些简单的东西对于有限的情况,这里有一个修改版的@lucas-trzesniewski 的 sub 来解决这些问题:

sub getAminoAcids
  {
    my $mrna = @_;
    $mrna =~ s/\s+//sg;
    $mrna = lc($mrna);
    my @proteins = ();
    while($mrna =~ /(aug(?:[acgu]{3})*?)uga/g)
      {
        $cds = $1;
        push(@proteins,"");
        while($cds =~ /(...)/g)
          {$proteins[-1] .= $aminoAcidMap{$1}}
      }
    return(@proteins);
  }

这假设您不想在蛋白质字符串中打印停止字符。它还可以具有诸如错误检查之类的附加功能。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-10-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多