mkHun
mkHun

Reputation: 5927

Negative matching regexp is not working in perl?

negative regex for perl string pattern match I seen this question and answer but which answers are not suited for my problem. But my question also like this, My script below

 use warnings;
 use strict;
 my @data = <DATA>;
 my @match = grep{m/^SEQ.+(!?ALA)/g} @data;
 print "@match\n";
 __DATA__
 SEQ HMK 112 ALA 123 
 SEQ ALA 322
 SEQ 121 ALA 333
 SEQ 114 PHE 443
 SEQ 11433 GLY 332
 SEQ 1123 VAL 121
 SEQ 1121 ALA 321
 SEQ 981 TRP 44532
 SEQ 887 TRP 90
 SEQ 11 HIS SPR 443
 HTTM SHH 121
 HTTM MME 221
 HTTM VZE 9
 EXP 112
 EXP 334 SMZ 

I expect, First check the beginning of the word SEQ But not match ALA line. I expect output is:

SEQ 114 PHE 443
SEQ 11433 GLY 332
SEQ 1123 VAL 121
SEQ 981 TRP 44532
SEQ 887 TRP 90
SEQ 11 HIS SPR 443

How can i do this

Upvotes: 1

Views: 191

Answers (2)

Toto
Toto

Reputation: 91498

You're really close, the regex should be:

my @match = grep{m/^SEQ(?!.+ALA)/} @data;

Just put the pattern .+ inside the negative lookahead.
If it's outside, every lines match because you"re searching for a line that begins with SEQ followed by any number of any character (ie. SEQ HMK 112 ALA 123 matches) then something that is not ALA, -> OK because there is not ALA after the whole line.

Upvotes: 4

Sobrique
Sobrique

Reputation: 53498

while ( <DATA> ) {
    next if m/ALA/;
    print if m/^SEQ/;
}

I'm sure someone can give you a regex-based answer, but this IMO is clearer what's going on.

I think you've two problems with negative matching. One is that .+ is greedy - so your 'ALA' is matching that, and the 'negative match' is true. The other is - you've got the ?! the wrong way around.

Upvotes: 4

Related Questions