I rarely come across situation where I need Possessive quantifiers to do something that Greedy quantifiers could not perform.

Greedy Reluctant Possessive Meaning

X?

X??

X?+

X, once or not at all

X*

X*?

X*+

X, zero or more times

X+

X+?

X++

X, one or more times

X{n}

X{n}?

X{n}+

X, exactly n times

X{n,}

X{n,}?

X{n,}+

X, at least n times

X{n,m}

X{n,m}?

X{n,m}+

X, at least n but not more than m times

Today, I have this json with inconsistent :, : , : . I want to find "type" that is not "Fruit" or "Vegetables" in IntelliJ. This could be a large file is in collabration so I have to retain the format to avoid creating conflict.

"type":"Fruits"
"type": "Vegetables"
"type" : "Grains"

The IntelliJ search uses Java Pattern for regex. Possessive quantifiers is perfect to go with zero-width negative look ahead group.

"type"[^"]++(?!"Fruit"|"Vegetables")

To break down:

"type" would match "type"

[^"]++ would match any of :, : , :

(?!"Fruit"|"Vegetables") would match "Grains" but not "Fruits" or "Vegetables"

For positive searching either "Fruit" or "Vegetables", Greedy quantifier would work. However, it doesn’t work for negative search as the backtracking would found something within the wildcard [^"]+ to get through the negative lookahead group.

"type"[^"]+(?!"Fruit"|"Vegetables")

In this case, [^"] would backtrack from : to : and that would cause (?!"Fruit"|"Vegetables") to match "Fruits"

Alternatively, we could move the Greedy quantifiers into the negative lookahead group.

"type"(?![^"]+("Fruit"|"Vegetables"))