skip to Main Content

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')

2

Answers


  1. 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)
    Login or Signup to reply.
  2. 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)}`)
    )
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search