I need PCRE2 regex to find all occurences of "no" as well as first and last occurences of "yes".
Expected results:
"no/yes" - expect two matches: "no" and "yes"
"no/yes/word/yes/no" - expect four matches: "no", "yes", "yes", "no"
"yes/yes/no/word/yes" - expect three matches: first "yes", "no", third "yes"
"yes/no/yes/yes" - expect three matches: first "yes", "no", third "yes"
I try this regex but it don't work as expected with "yes/no/yes/yes".
This subtask can make me happy with main goal.
CodePudding user response:
You are overthinking it.
There is no real point in using ONE regex to replace them all.
Just use multiple regexes.
s.replace(/yes/, ' ').replace(/yes(?!.*yes)/, ' ').replaceAll(/no/g, '-')
Also, there's no real way to replace one entry exept replacing it
CodePudding user response:
You can achieve your desired result, if you can use PCRE2 replacement string conditionals. You can use this regex (whitespace added for clarity, either use the x
flag or delete the newlines between alternations):
(no)|
(yes)(?!.*yes)|
((?!(?=(?<a>[\s\S]*))(?<b>yes.*(?=\k<a>\z)|(?<=(?=x^|(?&b))[\s\S])))yes)
It matches one of:
(no)
:no
(captured in group 1)(yes)(?!.*yes)
:yes
not followed byyes
(captured in group 2)((?!(?=(?<a>[\s\S]*))(?<b>yes.*(?=\k<a>\z)|(?<=(?=x^|(?&b))[\s\S])))yes)
: this is the equivalent of a variable length negative lookbehind for(?<!yes.*)(yes)
with theyes
captured in group 3. For the derivation of this part of the regex, see this blog post.
You can then use conditional replacements, replacing group 1 with -
and groups 2 and 3 with
${1: -: }
For input of
no/yes
no/yes/yes/no
/yes/yes/no/yes
no/word/no/yes/yes/yes/no
yes/no
yes/no/yes/word/yes
/word/yes/no/no/no/yes/yes
yes/no/yes/yes
This gives:
-/
-/ / /-
/ /yes/-/
-/word/-/ /yes/ /-
/-
/-/yes/word/
/word/ /-/-/-/yes/
/-/yes/