skip to Main Content

I have this regex

const regex = new RegExp(/^${[a-z][a-z0-9_]*}/${[a-z][a-z0-9_]*}$/, 'g');

that matches the string "${total_123}/${number_items}". Next, I want to extract the substrings total123 and number_items and set them as

const numerator = total_123 and const denominator = number_items. I’m not exactly sure how to do so.

3

Answers


  1. const regex = new RegExp(/^${([a-z][a-z0-9_]*)}/${([a-z][a-z0-9_]*)}$/, 'g');
    const string = "${total_123}/${number_items}";
    
    const matches = string.match(regex);
    
    if (matches) {
      const numerator = matches[1];
      const denominator = matches[2];
    
      console.log("numerator:", numerator); // "total_123"
      console.log("denominator:", denominator); // "number_items"
    }
    

    The parts enclosed in parentheses in the regex pattern represent groups. These groups can be individually captured using matches array, with the elements at index 1 and 2. This allows you to capture the expressions enclosed in parentheses separately.

    Login or Signup to reply.
  2. You need to store the variables in an object, then access its properties as needed:

    const variables = {
      total_123: 42,
      number_items: 0xf00
    };
    
    // Destructure the match, take the second and third element but skip the first.
    const [, group1, group2] = text.match(regex);
    
    const numerator = variables[group1];
    const denominator = variables[group2];
    

    Also, just declare your regex using the literal syntax:

    const regex = /^${([a-z][a-z0-9_]*)}/${([a-z][a-z0-9_]*)}$/;
    

    Do note that, since your regex doesn’t have a m flag, ^ means the beginning of the string and $ the end. That being said, we can get at most one match, and the g flag is not necessary (it even prevents us to access the groups if we use .match() and not .matchAll(), in fact).

    Try it:

    console.config({ maximize: true });
    
    const regex = /^${([a-z][a-z0-9_]*)}/${([a-z][a-z0-9_]*)}$/;
    const text = '${total_123}/${number_items}';
    
    const variables = {
      total_123: 42,
      number_items: 0xf00
    };
    
    const match = text.match(regex);
    console.log({match});
    
    // fullMatch is not needed, it's just there for the sake of readability.
    const [_fullMatch, group1, group2] = match;
    console.log({group1, group2});
    
    const numerator = variables[group1];
    const denominator = variables[group2];
    
    console.log(`${numerator}/${denominator}`);
    <script src="https://gh-canon.github.io/stack-snippet-console/console.min.js"></script>
    Login or Signup to reply.
  3. First some remarks:

    • You don’t need to call the RegExp constructor. Just use a regex literal.
    • As you can have more than one match with g flag, you need a loop
    • You could use named capture groups, like (?<numerator> )

    Code:

    const regex = /^${(?<numerator>[a-z][a-z0-9_]*)}/${(?<denominator>[a-z][a-z0-9_]*)}$/g;
    const s = "${total_123}/${number_items}";
    
    for (const {groups: {numerator, denominator}} of s.matchAll(regex)) {
        console.log(numerator, denominator);
    }
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search