iagowp
iagowp

Reputation: 2494

How to negative look ahead using vim/grep

I was able to build my Regex on regxr.com

/.*GET.*(?!(Chrome)).*"$/

I want my regex to not match this line:

node_lum.log:C3 2019-04-15 15:00:28.954 NOTICE: 6ms 77.172.180.249 GET /users/zone/active.json?customer_name=hl_e5d4a218 HTTP/1.1 200 - - "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36"

And match this

node_lum.log:C3 2019-04-15 15:00:28.954 NOTICE: 6ms 77.172.180.249 GET /users/zone/active.json?customer_name=hl_e5d4a218 HTTP/1.1 200 - - "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) asd/73.0.3683.103 Safari/537.36"

I've tried using both vim and grep.

On vim, I tried

/*GET.*\(Chrome\)\@!.*"$
/*GET.*\(\(Chrome\)\)\@!.*"$

On grep, I tried

grep -P '.*GET.*(?!(Chrome)).*"$' ./grep.txt
grep -P '.*GET.*(?!Chrome).*"$' ./grep.txt

None of those got me the matches I wanted

Upvotes: 2

Views: 332

Answers (1)

Wiktor Stribiżew
Wiktor Stribiżew

Reputation: 626932

In grep, you should remove the first .* (it is redundant) and make sure the next .* is inside the negative lookahead:

GET(?!.*Chrome).*"$
      ^^

See the regex demo and a Regulex graph:

enter image description here

Details

  • GET - a GET substring
  • (?!.*Chrome) - no Chrome is allowed after any 0+ chars other than line rbeak chars
  • .*"$ - any 0+ chars other than line break chars, as many as possible, and a " at the end of the line must be present.

In Vim, it will look like

GET\(.*Chrome\)\@!.*"$

The \(.*Chrome\)\@! is the negative lookahead equivalent.

Upvotes: 1

Related Questions