I have the following String:
"Hello, don't match this: !{SUM(1,2)}" but match this: !{SUM(1,2)} "And not this: !{MEAN(3,4)}"
I currently have the following regex (\!{(?:\[??[^\[]*?\}))
to match all !{}
How could I add to this to match all !{.} that are NOT inside a pair of double quotes?
Not sure if this is even possible since the middle section would technically be between 2 double quotes..
Thanks for any help!!
CodePudding user response:
https://regex101.com/r/QAmbym/1
^(?>".*"|[^!{}])*\K!{.*}
^
- Anchor to the start of the string. This is important because of what's next.
(?>
- atomic group. once matched, don't backtrack.
".*"
- Consume anything in quotes. Once consumed, the engine won't backtrack for it
|
- or
[^!{}]
- match anything that isn't the characters we're interested in. These are still part of the atomic group, so anything consumed can't be matched.
)*
- Close the atomic group and match the entire group 0 or more times.
\K
- reset the pattern. Throw away everything matched up until this point.
!{.*}
- What you're looking for.
So because we're starting out anchored, we're going to consume anything that is in quotes, or definitely isn't what we want. It's consumed in a way that won't let the engine backtrack for it. Then once we get to what we're looking for, we throw everything away. This means anything in quotes won't be matched.
Edit:
Thanks to @Nick posting the link to the other thread, I've found there's a much simpler way to go about it that works with javascript:
https://regex101.com/r/Y3QHTc/1
".*"|(!{.*})
".*"
match anything in quotes, ungrouped
|
or
(!{.*})
match what you're looking for in group 1.
While technically you're matching unwanted strings, you can filter out everything that doesn't return a group 1, leaving you with what you're looking for.
CodePudding user response:
Since atomic groups are not supported in JS, you can try this simple method:
- Match everything that is inside qoutes and remove it
- Check if the remaining string has the things that you want to match !{. }
let s = `"Hello, don't match this: !{SUM(1,2)}" but match this: !{SUM(1,2)} "And not this: !{MEAN(3,4)}"`
let pattern = /!{. }/gm
if (pattern.test(s.replaceAll(/". ?"/gm, ''))) {
console.log("Match")
}
else {
console.log("Not match")
}
Here s.replaceAll(/". ?"/gm, '')
gives you: but match this: !{SUM(1,2)}
then you apply the pattern !{. }
to match everything that is between !{
and }
, on it.