Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Regex 找出合适的匹配正则表达式_Regex_Perl - Fatal编程技术网

Regex 找出合适的匹配正则表达式

Regex 找出合适的匹配正则表达式,regex,perl,Regex,Perl,我对编程比较陌生。我目前正在学习Perl,我遇到了一个逻辑问题,这使我无法正确地完成脚本。任何帮助都将不胜感激!!提前感谢您的有用见解 大部分程序已经编写好了,这是让我头疼的最后一步 我有一个变量$RNA,它以任意顺序获取核苷酸序列(acgu)。例如: $RNA = agcuaggaaggguuuugauag 等等 我已经创建了一个散列,其中每3个核苷酸字符或密码子(例如uga)被分配给一个定义的氨基酸。例如: % my AminoAcid = ( ggg => "G", .

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

大部分程序已经编写好了,这是让我头疼的最后一步

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

$RNA = agcuaggaaggguuuugauag
等等

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

% my AminoAcid   = (
  ggg => "G",
  ...
);
我想做的是,每当它读取
$RNA
字符串中的起始密码子
aug
时,打印与哈希中密码子对应的已定义氨基酸(大写字母),并且每当它读取终止密码子
uga
时,停止打印哈希中已定义的氨基酸

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

注意:在读取起始密码子(
aug
)之前,它应该忽略前三个
aaa
,在读取终止密码子(
uga
)之后,它应该忽略前三个
aug
),如果它在字符串的任何地方再次看到起始密码子,则重复相同的过程

我尝试了多种想法,但没有一个能接近于描述最后一部分代码的正确编写方式。我可能不完全明白背后的逻辑

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

让我们从这个开始:

my $rna = "aaaaugcccgggugaccccccccc";
my %aminoAcidMap = ( ggg => "G", ccc => "C" );
第一步是提取
aug
uga
之间的相关部分:

$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
将包含
aug
uga
之间的部分

现在,要进行映射,您可以执行以下操作:

my $aminoAcids = $pattern =~ s/[acgu]{3}/$aminoAcidMap{$&}/ger;
这将用散列中的值替换每个密码子

如果您将所有内容都打包到sub中,您将获得:

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

如果将逻辑放入代码组(?{})

多条线路的Mod
注-如果需要重新校准(通过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

@lucas trzesniewski的sub非常好而且非常紧凑,但它有一些缺点:它不处理分散的硬回报,只找到第一个蛋白质,不打印第一个蛋氨酸,并用隐式回报修改$1/$(这是我试图避免的)。这是一个改进。注意,我自己有一个非常精巧的翻译脚本,它可以处理更多的情况(例如,重叠的阅读框、模棱两可的核苷酸、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);
  }

这假设您不想在蛋白质字符串中打印停止字符。它也可能有额外的功能,比如错误检查。

8月的
aug
是否必须在一个可以被3整除的索引上,或者它可以出现在任何地方?你能发布你尝试过的代码吗?你好,卢卡斯,非常感谢!!!!我非常感谢你的帮助!我唯一不太明白的是“子”块。你能给我解释一下你到底做了什么吗?例如,哪个语句在读取终止密码子时停止将密码子翻译成氨基酸?提前谢谢你!!还有,请原谅我的无知,有没有更简单的方法来完成同样的事情?我尝试了for、while和until循环。因为我不是专家,我想我可能误用了它们。再次感谢你@Dimitri
sub
是一个子例程/函数,用于代码重用。例如:
print getAminoAcids“aaaaugcccggugcccccccccc”为了做到这一点,我只是从答案中提取了另一个代码,去掉了临时变量,并将它们放在一起。终止密码子由正则表达式读取(以
/aug
开头的表达式)-有关更多详细信息,请参阅。是的,我并不是真的追求简单易懂的方式,而是追求最简洁、最高效的方式(用3行代码完成任务)。当然,Perl不是最容易学习的语言。上面的代码不会打印空行。你复制粘贴了整个代码吗?是的,代码中只有一个
print“\n”
,因为在这个块中设置了
$on
,所以它总是打印
\n
+
$AminoAcid{$^n}
,其中
$^n
是最后一个捕获缓冲区的内容,并且是该哈希值的“键”。如果密钥不存在,则会自动创建一个空白值。我会为你做一些错误检查。好的,我想我理解了,调整了多行,并为密钥的存在添加了一些错误检查。