mortensen
mortensen

Reputation: 1237

Replace matches with regex

I am trying to replace matches of text between dollar signs.

So the text $match$ inside Some text and $some text that matches$. should be replaced.

I have tried

text.replace(/\$.*?\$/g, function (match) {
  return '_' + match + '_';
}

This works. The problem is that I want to do evaluate the match inside this function, but sometimes the evaluation didn't work, and in these cases I just want to return the original match. So it is something like

text.replace(/\$.*?\$/g, function (match) {
  try {
    return evaluate(match);
  } catch (e) {
    return match;
  }
}

But with my current regex, the match contains the dollar signs from the original text. I want it to omit the dollar signs, but if the evaluation fails, then I want the original dollar signs back.

What I could do is

text.replace(/\$.*?\$/g, function (match) {
  try {
    return evaluate(match.replace(/\$/g, ''));
  } catch (e) {
    return match;
  }
}

but isn't it possible in a more elegant way?

Upvotes: 0

Views: 69

Answers (1)

Scott Sauyet
Scott Sauyet

Reputation: 50797

Something like this might do:

const evaluate = function(str) {
    if (str && str.startsWith("t")) {return str.toUpperCase();}
    throw "Gotta hava a 'T'";
};

"ab$test$cd $something$ that is $tricky$.".replace(/\$([^$]*)\$/g;, function(str, match) {
    try {
        return evaluate(match);
    } catch(e) {
        return str;
    }
}); //=> "abTESTcd $something$ that is TRICKY."

But I agree with the comment that you might be better returning a different signal (undefined? null?) from evaluate rather than throwing for this case. And then the function body could simply be something like:

        return evaluate(match) || str;

The point is the capturing group in the regex: /\$([^$]*)\$/g;, which becomes a parameter to the replacement function.

Upvotes: 1

Related Questions