perl正则表达式替换但更改为数字

时间:2014-02-04 11:40:10

标签: regex perl

我有一个像

这样的字符串
 /translation="MNVTRLYFRVAGTKQLARYVHKYAAYSSTSFQKKKSHFPSPATL                     DHPDAGEDAFINLRNENYILNAVFDGVGGWANVGIDPSIFSWGLVREIKKVFNNSDEF                     QPSPLTLLSKAYAALKKSNTVEAGSSTACLTLFNCGNGKLHSLKYVICSLVHKFLLTL                     FQALVTQDFLSLEMVLSIMHHLPKYSNLICHINWLYFLGTIVPLKTLGLKWDKQLCTT                     LKTMTW"                     /translation="MEKEDIEKLFQEVKESLQYSYCPYSNFAVGACVVSDDKNTYIYG                     ANVENASYGNCICAERVAITKAVSMGYTKFMAIGVMSAKGRVTPCGICRQVIREFSKD                     INVYMFHDDGGYDMKTIEELLPDSFGPDDLK"

我怎样才能得到一个正则表达式来获取所有大写字母,比如

MNVTRLYFRVAGTKQLARYVHKYAAYSSTSFQKKKSHFPSPATLDHPDAGEDAFINLRNENYILNAVFDGVGGWANVGIDPSIFSWGLVREIKKVFNNSDEFQPSPLTLLSKAYAALKKSNTVEAGSSTACLTLFNCGNGKLHSLKYVICSLVHKFLLTLFQALVTQDFLSLEMVLSIMHHLPKYSNLICHINWLYFLGTIVPLKTLGLKWDKQLCTTLKTMTWMEKEDIEKLFQEVKESLQYSYCPYSNFAVGACVVSDDKNTYIYGANVENASYGNCICAERVAITKAVSMGYTKFMAIGVMSAKGRVTPCGICRQVIREFSKDINVYMFHDDGGYDMKTIEELLPDSFGPDDLK

我尝试使用~s / translation //但它无法正常工作

当我使用~s // translation =“//它改为

518446744073709551614                     DHPDAGEDAFINLRNENYILNAVFDGVGGWANVGIDPSIFSWGLVREIKKVFNNSDEF                     QPSPLTLLSKAYAALKKSNTVEAGSSTACLTLFNCGNGKLHSLKYVICSLVHKFLLTL                     FQALVTQDFLSLEMVLSIMHHLPKYSNLICHINWLYFLGTIVPLKTLGLKWDKQLCTT                     LKTMTW"18446744073709551614                     ANVENASYGNCICAERVAITKAVSMGYTKFMAIGVMSAKGRVTPCGICRQVIREFSKD                     INVYMFHDDGGYDMKTIEELLPDSFGPDDLK"

当我使用$ dna = ~s / [^ A-Z] // g时更新; 它显示在替换中使用未初始化的值$ _(s ///) 18446744073709551615

我的部分代码

  open IN, '</root/Desktop/GeneBank.txt' or die "Cannot open file : $!";;
  while (<IN>) {
  chomp $_;


  if (/^\/\/\n/) { 

  last; 
  } 
  elsif (/"$/&& $in_tran==1) { 
  $in_sequence = 0; 
  $in_tran=0;
  $_= ~s/[^A-Z]//g;
  $dna.=$_;


  }
  elsif ($in_sequence==1) { 
  $_= ~s/[^A-Z]//g;
  $dna .= $_; 

  }
  elsif (/^\s*\Stranslation/) { 
  $in_sequence = 1; 
  $in_tran=1;
  $_= ~s/[^A-Z]//g;
  $dna.=$_;
  #print $line;
  } 

  elsif (/^\s*CDS/) { 

  push(@$annotation, $line); 
  }
  }
  close IN;

  print $dna;

但是〜s / [^ A-Z] // g将所有字符都改为数字,它显示为

         1844674407370955158018446744073709551594184467440737095515941844674407370955159418446744073709551593184467440737095515801844674407370955159418446744073709551593

3 个答案:

答案 0 :(得分:2)

更改所有行:

$_= ~s/[^A-Z]//g;

使用:

$_ =~ s/[^A-Z]//g;

或者,更好:

s/[^A-Z]+//g;

像你一样使用,~是按位否定。请参阅doc

答案 1 :(得分:2)

首先,将regexp替换应用于变量的binding operator一起写成=~ - 而不是= ~,其间有空格,Perl会将其解析为{{ 3}}(=)和assignment~)。因此,如果你写:

$_= ~s/[^A-Z]//g;

Perl将首先将替换s/[^A-Z]//g应用于$_(默认情况下,因为=~没有绑定任何其他内容),然后获取其返回值(替换数量) ,如果数字为零,则为空字符串),否定它(按位)并将按位否定的结果分配回$_,覆盖替换的结果。

修复它的方法就是不在=~之类的运算符中间包含空格。另请注意,语句$_ =~ s/foo/bar/;s/foo/bar/;语句完全相同;如果您要将替换应用于某些变量其他而不是=~,则只需要$_


最后,一旦你修复了这些问题,你仍然会遇到如何在正则表达式中包含文字斜杠(/)的问题。为此,您(至少)有两个解决方案:

  1. bitwise negation,就像这样:

    s/\/translation=//;
    
  2. 如果您宁愿避免使用Quote it by putting a backslash before it,请使用替代的正则表达式分隔符,例如:

    s!/translation=!!;
    

    或:

    s(/translation=){};
    

答案 2 :(得分:1)

如果你只想要大写字母,那么用''字母表中不是大写字母的任何内容替换:

$string =~ s/[^A-Z]//g;

关于前导斜杠,您可以使用/转义\

$string =~ s/\/translation="//;

或者,您可以使用除“/”之外的其他分隔符:

$string =~ s{/translation="}{};

http://perldoc.perl.org/perlretut.html查看更多内容并搜索“分隔符”。