【问题标题】:Regular Expression - Perl: Adding Specificity正则表达式 - Perl:添加特异性
【发布时间】:2013-08-06 21:35:22
【问题描述】:

我想编写一个特定的正则表达式以特定的文件格式执行以下操作。

它应该能够用正则表达式检查第三个字段是否只是一个 O 或在 O 之后有任何内容。

目前,我使用如下语法:

   if ($line !~ /^ATOM\s+\d+\s+(O)/)
   {

   }

你们能帮帮我吗?

  ATOM     284  OD1  ASN 1   34   -7.92000  -6.74600  -4.73800 O_2    1 2 -0.55000 0   0
  ATOM     308  O    LEU 1   35  -10.48500 -13.59200  -8.35100 O_2    1 2 -0.51000 0   0

我希望能够从文件中打印出包含 O 之后的内容的行(例如 OD1 行)。我应该可以只用一个 O 来删除这些线条。

【问题讨论】:

  • 你能详细说明一下吗?从您的问题中不清楚您的实际期望是什么?该文件的预期输出应该是什么?
  • 如果您正在解析 pdb 文件,请使用 substr 获取每个字段的字符。使用正则表达式解析值无效。

标签: regex perl


【解决方案1】:

只需添加\S(意思是“非空格字符”):

/^ATOM\s+\d+\s+O\S/

顺便说一句,我的印象是您实际上并不了解正则表达式?我推荐the perlretut ("Perl regular expressions tutorial") manpage

【讨论】:

    【解决方案2】:

    您当前使用的!~ 不匹配。如果您希望它匹配,则必须将其更改为 =~。您也不需要括号是O() 用于捕获组。如果你想捕获这个群体,你可以这样做 (O[A-Za-z0-9])。

    if ($line =~ /^ATOM\s+\d+\s+O/)
    # we don't care what's after the O, could be nothing or some characters
    

    if ($line =~ /^ATOM\s+\d+\s+(O[a-zA-Z0-9]*)/)
    # this will capture OD1 or just O in $1
    

    或者如果要查看0后面是否有字符,可以使用

    if ($line =~ /^ATOM\s+\d+\s+(O[a-zA-Z0-9]+)/)
    # this would only capture OD1 in $1
    

    【讨论】:

      【解决方案3】:

      您可以使用split 拆分该字段:

       my $field = ( split /\s+/, $line )[2];
      

      这将使正则表达式更容易你想要更容易做。另外,它使您所做的事情更加明显:

       if ( $field =~ /^O/ ) {
           here be dragons...
       }
      

      事实上,您可能希望对所有字段都这样做,以使其更易于操作。由于我不知道您的字段是什么意思,所以我只是称它们为$fld1$fld2 等。

      my ( $fld1, $fld2, $fld3, $fld4, ... ) = split /\s+/, $line;
      if ( $fld3 =~ /^O/ ) {
          here be dragons...
      }
      

      现在,您可以轻松引用程序中的各个字段。

      【讨论】:

        【解决方案4】:

        如果你不想使用正则表达式,你可以像@David-W 所说的那样使用 split

        my @fields = split /\s+/, $line;
        ##now $field[2]
        if ($fields[2] ne 'o'){
            ##this line has o and other letters
        }
        

        但这会比正则表达式慢得多,尤其是对于大型数据文件

        至于正则表达式,您的数据文件以空格开头(显然) 所以你的正则表达式应该如下

        if ($line !~ /^\s+ATOM\s+\d+\s+(O)\s+/){
            ##this line has o with other letters beside it
        } else {
            ## this line only has o in field 3
        }
        

        在开头添加^\s+或完全删除^标记

        $line !~ /ATOM\s+\d+\s+(O)\s+/
        

        然后在 o 之后(最后)添加 \s+ 以确保它后面紧跟空格

        如果您对捕获字段值不感兴趣,则最好捕获组 (o)

        if ($line !~ /ATOM\s+\d+\s+O\s+/) {
            #...
        } else {
            #...
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2012-07-10
          • 1970-01-01
          • 1970-01-01
          • 2019-04-21
          • 1970-01-01
          • 2012-07-22
          • 1970-01-01
          相关资源
          最近更新 更多