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.
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 by yes
(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 the yes
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/+