I'm trying to build a regex that will replace the tokens %aa% and %cc% inside a string. All the cases are listed below:
1) /%aa%/%cc%/bb => should replace only %cc%
2) /%aa%/%cc%/ac => should replace only %cc%
3) /bb/%aa%/%cc% => should replace only the last %cc%
4) /bb/%aa% => should replace %aa%
5) /bb/ac/%aa%/%cc%/ac/bb => should replace only the last %cc%
I have the following regex which covers most of the case expect 2 and 5, basically those that contain the same chars as the tokens.
Regex pattern: %(?|(?|aa)|(?|cc))%(?=[^(aa|cc)]*($)+)
Language is PHP.
Thanks.
Your regex contains redundant branch reset groups ((?|...|...)
) and the corrupt grouping that is placed into a character class [^(aa|cc)]*
, and an end of string anchor quantified (($)+
), which is also a user error (no need to capture the anchor here and it is enough to test it once).
You can use the following regex:
'~%(?:aa|cc)%(?!.*%(?:aa|cc)%)~'
See regex demo
For standalone strings, you can also add the ~s
singleline (DOTALL) modifier: '~%(?:aa|cc)%(?!.*%(?:aa|cc)%)~s'
.
The (?!.*%(?:aa|cc)%)
negative lookahead fails a match if either aa
or cc
appear after the aa
or cc
found so far.