Cuge
Cuge

Reputation: 21

Regex match chars not between 2 specific chars or words

i'm trying to make this regex work but i only had an half-success.

So far i could make this work:

match every ';' that is not between '[]'

with this regex: ;(?![^\[]*\])

But now comes my problem... i should also add this limitation:

match every ';' that is not between '[' and ']' or 'XXX' and 'ZZZ'

So for example in this text:

aaa **;** bbb **;** [ ccc *;* ddd ] eee **;** XXX qweasd *;* qwesad ZZZ

the third and last ';' should not match

Upvotes: 1

Views: 54

Answers (2)

Jan
Jan

Reputation: 43169

If (*SKIP)(*FAIL) is an option (PHP, PyPi Regex the like), you might get along with

(?:\[[^][]+\]|XXX.+?ZZZ)(*SKIP)(*FAIL)|;

See a demo on regex101.com.


Explanation:

(?:             # non-capturing parenthesis
    \[[^][]+\]  # anything between [ and ]
    |           # or
    XXX.+?ZZZ   # XXX ... ZZZ
)(*SKIP)(*FAIL) # all of this should be skipped
|               # ... or ...
;               # match a ;

Upvotes: 1

Tim Biegeleisen
Tim Biegeleisen

Reputation: 521289

This pattern seems to be working:

;(?![^[]*\])(?!((?!XXX).)*ZZZ)

Explanation:

;                   match a semicolon
(?![^[]*\])         assert that we cannot look forward and see a ] without also seeing
                    an opening [
                       -> this implies that the semicolon is not in between []
(?!((?!XXX).)*ZZZ)  assert that we cannot look forward and see ZZZ without
                    first seeing XXX
                       -> this implies that the semicolon is not in between XXX and ZZZ

Demo

Note that this solution assumes that you would not have nested [] brackets anywhere, or nested XXX...ZZZ, but rather only single level.

Upvotes: 1

Related Questions