HiseaSaw
HiseaSaw

Reputation: 165

Regex - everything but anything within parenthesis

Having, let's say:

fieldA=20 and (fieldB=date() and (fieldC=35 and fieldD=40)) and fieldE = 100

I'm trying to replace outter "and" words, something:

fieldA=20 zzz (fieldB=date() and (fieldC=35 and fieldD=40)) zzz fieldE = 100

I've tried for hours, with no success. I could find some answers regarding how to get everything inside either parenthesis or brackets. The following expression is getting everything inside parenthesis, but I don't actually know how to write an expression that ignores just that:

\(([^()]*+|(?R))*\)    # retrieves "(fieldB=date() and (fieldC=35 and fieldD=40))"

Any help would be appreciated.

Upvotes: 3

Views: 129

Answers (2)

Wiktor Stribiżew
Wiktor Stribiżew

Reputation: 627488

Your \(([^()]*+|(?R))*\) pattern contains a whole pattern recursion construct (?R) allowing to match nested parentheses and everything inside them. What you need is to omit everything matched with this subpattern and match and as whole words outside those. We need to put this whole subpattern into a capturing group and replace (?R) with (?1) to only recurse the first capturing group pattern, not the whole pattern.

The (*SKIP)(?!) construct can be used to omit currently matched alternative in a PCRE regex.

Thus, use

(\(([^()]*+|(?1))*\))(*SKIP)(?!)|\band\b

See the regex demo

In short,

  • (\(([^()]*+|(?1))*\))(*SKIP)(?!) - match nested parentheses with everything inside, omit this matched text and go on analyzing the string
  • | - or...
  • \band\b - match and return the whole word and

Upvotes: 2

Shafizadeh
Shafizadeh

Reputation: 10380

Try this pattern:

/^(.*?)(?:and)(.*)(?:and)(.*)$/

And replace with:

$1 zzz $2 zzz $3

Online Demo

Upvotes: 2

Related Questions