I am trying to refactor the method below to use regex instead of indexOf:
hasMatch(value: any): boolean {
if (isDefined(value)) {
const valueStr = JSON.stringify(value);
return valueStr.indexOf('{{') > -1 && valueStr.indexOf(':') > -1;
} else {
return false;
}
}
Currently it simply checks if there are double brackets “{{” and a colon in the string. This means I matches colons outside of the replacement strings, which I don’t want.
I need to only return a match if a colon exists between two double brackets with key/value pairs like: {{key:value}}
Here is what I’ve cobbled together using some examples here (I’m obviously a complete regex newb):
const matches = valueStr.match(/{{({^}{}*)}}/g).map(x => `[${x.replace(/[^:]/g, '')}]`)
But I’m currently stuck on this error:
main.js:66071 ERROR TypeError: Cannot read properties of null (reading 'map')
You can use a regex that matches a colon between {{
(both brackets need to be escaped with ) and
}}
, with optional non-}
characters in between:
const valueStr = "{{key: value}}"
console.log(valueStr.match(/{{[^}]*:[^}]*}}/) != null)
0
Depending on the allowed characters for the key
and value
and the key and value can not be empty strings:
{{s*w+s*:s*w+s*}}
Regex demo
Or a more strict version without matching whitepace chars:
{{w+:w+}}
Regex demo
To match a key and a value, where the key and the value are not one of {
}
:
{{[^{}:]*[^s{}:][^{}:]*:[^{}:]*[^s{}:][^{}:]*}}
The pattern matches:
{{
Match literally[^{}:]*
Match optional chars other than{
}
:
[^s{}:]
Match a non whitespace character other than{
}
:
[^{}:]*
Match optional chars other than{
}
:
:
Match a colon[^{}:]*[^s{}:][^{}:]*
The same pattern as before the colon}}
Match literally
Regex demo
const regex = /{{[^{}:]*[^s{}:][^{}:]*:[^{}:]*[^s{}:][^{}:]*}}/;
[
"{{key:value}}",
"{{ key : value }}",
"{{ke#$%$%y:val#!$#$^$%^$%^^%$*&%ue }}",
"{{:}}",
"{{key:}}",
"{{key: }}",
"{{:value}}",
"{{key:value:test}}"
].forEach(s =>
console.log(`${s} --> ${regex.test(s)}`)
)