我想编写一个特定的正则表达式,以特定的文件格式执行以下操作。
它应该能够用正则表达式检查第三个字段是否只是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来删除这些行。
答案 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 {
#...
}