I have two strings:
"~if~ text_if_true ~end~"
"~if~ text_if_true ~else~ text_if_false ~end~"
All I want is a regexp with give following output:
for 1. =>
group 1 = text_if_true
for 2. =>
group 1 = text_if_true, group 2 = text_if_false
I tried:
~if~(.*?)(?:~else~)(.*?)~end~
Work fine on II but not on I because the ~else~ is needed
if I use
~if~(.*?)(?:~else~)?(.*?)~end~
With a ? behind (?:~else~) (for 0 or 1 matches) the text_if_true and the text_if_false is in the first group.
Is there a easy way to solve the problem?
const regex = /~if~(.*?)(?:~else~)(.*?)~end~/gm;
const regex2 = /~if~(.*?)(?:~else~)?(.*?)~end~/gm;
const str = `~if~ text_if_true ~else~ text_if_false ~end~
~if~ text_if_true ~end~`;
let m;
console.log('without ? quantifier')
while ((m = regex.exec(str)) !== null) {
// This is necessary to avoid infinite loops with zero-width matches
if (m.index === regex.lastIndex) {
regex.lastIndex++;
}
// The result can be accessed through the `m`-variable.
m.forEach((match, groupIndex) => {
console.log(`Found match, group ${groupIndex}: ${match}`);
});
}
console.log('with ? quantifier')
while ((m = regex2.exec(str)) !== null) {
// This is necessary to avoid infinite loops with zero-width matches
if (m.index === regex.lastIndex) {
regex.lastIndex++;
}
// The result can be accessed through the `m`-variable.
m.forEach((match, groupIndex) => {
console.log(`Found match, group ${groupIndex}: ${match}`);
});
}
Instead of making just the word ~else~ optional, you should make the whole of ~else~ (.*?) optional (I have also added some spaces so that the groups don't have leading or trailing spaces):
if~ (.*?)(?: ~else~ (.*?))? ~end
Demo
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With