Francois Carstens
Francois Carstens

Reputation: 487

Regex to exclude a substring

I am trying to match a param string but exclude any matches when a substring is present.

From my limited regex knowledge this should work to exlude any string containing "porcupine", but it's not. What am I doing wrong?

(\/animal\?.*(?!porcupine).*color=white)

Expected Outcome

| string                                          | matches? |
| ----------------------------------------------- | -------- |
| /animal?nose=wrinkly&type=porcupine&color=white | false    |
| /animal?nose=wrinkly&type=puppy&color=white     | true     |

Actual Outcome

| string                                          | matches? |
| ----------------------------------------------- | -------- |
| /animal?nose=wrinkly&type=porcupine&color=white | true     |
| /animal?nose=wrinkly&type=puppy&color=white     | true     |

Upvotes: 2

Views: 515

Answers (3)

Booboo
Booboo

Reputation: 44128

This may seem overly verbose but it is actually relatively efficient in the number of steps:

(?!\/animal.*?porcupine.*?color)\/animal\?.*color=white

See Regex Demo

If the input string consists of only one and only one occurrence of what you are trying to match and nothing else, then just use the following to ensure that porcupine does not occur anywhere in the input string:

(?!.*porcupine)\/animal\?.*color=white

The code:

import re

tests = [
    '/animal?nose=wrinkly&type=porcupine&color=white',
    '/animal?nose=wrinkly&type=puppy&color=white'
]

rex = r'(?!\/animal.*?porcupine.*?color)\/animal\?.*color=white'

for test in tests:
    m = re.search(rex, test)
    print(test, 'True' if m else 'False')

Prints:

/animal?nose=wrinkly&type=porcupine&color=white False
/animal?nose=wrinkly&type=puppy&color=white True

Upvotes: 0

Gustav Rasmussen
Gustav Rasmussen

Reputation: 3961

The .* searches anything for any number of times, greedily. So you could replace it with a literal search:

(\/animal\?nose=wrinkly\&type=(?!porcupine).*color=white)

See example here: https://regex101.com/r/HJiM2N/1

Upvotes: 0

Toto
Toto

Reputation: 91415

Use a Tempered Greedy Token:

/animal\?(?:(?!porcupine).)*color=white

Demo & explanation

Upvotes: 2

Related Questions