skip to Main Content

I have a string like this: "hello %{name} good %{middle} bye".

I’m trying to find an effective way to extract out the values in-between the braces, so ideally I would end up with an array of ["name", "middle"].

Using match I can almost get there. The following returns: ['%{name}', '%{middle}']:

"hello %{name} good %{middle} bye".match(/%{([w]+)}/g)

I’m not sure why it’s including the %, {, and } characters in the return though.

How can I adjust my regular expression to only match name and middle?

3

Answers


  1. You can use a named capturing group. In the example below, we name it value, and then extract those values during iteration of the regex matches:

    let s = "hello %{name} good %{middle} bye"
    
    let r = [...s.matchAll(/%{(?<value>[w]+)}/g)].map(i => i.groups.value)
    
    console.log(r)
    Login or Signup to reply.
  2. Try

    const str = "hello %{name} good %{middle} bye";
    const regex = /%{([w]+)}/g;
    let matches;
    const result = [];
    
    while ((matches = regex.exec(str)) !== null) {
      result.push(matches[1]);
    }
    
    console.log(result) // [ 'name', 'middle', 'another', 'example' ]

    Regards your question why is it including the %, {, and } characters in the return

    because the match() function in JavaScript returns the entire matched substring, including the %{ and }.

    A solution to this would be to use match[1] (or equivalent in a loop with exec()) allows you to access only the content captured within the parentheses ( ) in your regex pattern.

    Login or Signup to reply.
  3. You need to change your regex expression to capture the values inside the braces without the %, {, and } characters, you can modify it slightly.

    Existing: /%{([w]+)}/g => /%{(w+)}/g

    Refer the below examples:

    const str = "hello %{name} good %{middle} bye";
    const str1 = "hello %{aaa} good %{bbbb} bye";
    const str2 = "hello %{xyz} %{gtr} %{pqr} bye";
    
    const matches = str.match(/%{(w+)}/g);
    const matches1 = str1.match(/%{(w+)}/g);
    const matches2 = str2.match(/%{(w+)}/g);
    
    const values = matches.map(match => match.slice(2, -1));
    const values1 = matches1.map(match => match.slice(2, -1));
    const values2 = matches2.map(match => match.slice(2, -1));
    
    console.log(JSON.stringify(values));
    console.log(JSON.stringify(values1));
    console.log(JSON.stringify(values2));

    Also, this can be achieved via non regex-based approach as well:

    const str = "hello %{name} %{world} %{middle} bye";
    const str1 = "hello %{aaa} %{bye} %{bbbb} bye";
    const str2 = "hello %{xyz} %{gtr} %{pqr} bye";
    const startDelimiter = "%{";
    const endDelimiter = "}";
    
    function extractValues(input, startDelimiter, endDelimiter) {
        const values = [];
        let startIndex = 0;
    
        while ((startIndex = input.indexOf(startDelimiter, startIndex)) !== -1) {
            startIndex += startDelimiter.length;
            const endIndex = input.indexOf(endDelimiter, startIndex);
            if (endIndex === -1) {
                break; 
            }
            const value = input.substring(startIndex, endIndex);
            values.push(value);
            startIndex = endIndex + endDelimiter.length;
        }
    
        return values;
    }
    
    const result = extractValues(str, startDelimiter, endDelimiter);
    const result1 = extractValues(str1, startDelimiter, endDelimiter);
    const result2 = extractValues(str2, startDelimiter, endDelimiter);
    
    
    console.log(JSON.stringify(result));
    console.log(JSON.stringify(result1)); 
    console.log(JSON.stringify(result2)); 
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search