正则表达式 - Perl:增加特异性

时间:2013-08-06 21:35:22

标签: regex perl

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

它应该能够用正则表达式检查第三个字段是否只是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来删除这些行。

4 个答案:

答案 0 :(得分:1)

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

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

顺便说一下,我觉得你实际上并不知道正则表达式?我推荐the perlretut ("Perl regular expressions tutorial") manpage

答案 1 :(得分:0)

您目前使用的!~不匹配。如果您希望匹配,则必须将其更改为=~。您也不需要括号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

答案 2 :(得分:0)

您可以使用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...
}

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

答案 3 :(得分:0)

如果你不想使用正则表达式,可以使用split作为@ David-W说

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 {
    #...
}