views:

207

answers:

2

Multiline Test string:

dkdkdkdk dkdkdkdk dkdkdkd dkdkdkd "hello" dkdkdkdkdk dkdkdk "goodbye.hello"  dkdkdkd kdkdkd kdkdkdk "hello.goodbye.hello" dddd "test" ssss "http:x-y.f/z/z" "" "."
"http:/dkdkd/dkdkdk/dkdkdkdkdkdk.g"

I want to match every quoted string that contains "hello"

This matches every quoted string

\"(.+?)\"

This matches every quoted string that contains hello in it

\"(.*?)hello(.*?)\"

But this, does not match every quoted string that DOES NOT contain hello

\"(.*?)(?!hello)(.*?)\"

Thanks for any help!

+1  A: 

My initial answer is to need to apply the negative lookahead every time the dot matches, like so:

\"((?!hello).)*?\"

However there is a problem with this regular expression in targets that contain more than one quoted string -- the space between the closing quote of one string and the opening string of another quote is also a "quoted string" to this expression.

My suggestion is therefore to extract all quoted strings from your target using a simple "[^"]*" pattern, and then evaluate each match for the word(s) you want to disallow.

Daniel Vandersluis
Better use `"[^"]*"` instead of `".*?"`.
Gumbo
@Gumbo I don't see what difference that makes?
Daniel Vandersluis
@Daniel Vandersluis: It avoids unnecessary backtracking.
Gumbo
@Gumbo Fair enough.
Daniel Vandersluis
A: 

Try this

\"((?!hello).)*?\"
Paul Creasey
That's what I came up with at first, but I deleted my answer because it's got a problem; in the test string it won't match `"hello"`, but instead it'll match `" dkdkdkdkdk dkdkdk "`
Daniel Vandersluis
@Vandersluis, same here
Rubens Farias
Better use `"[^"]*"` instead of `".*?"`.
Gumbo