Home > OS >  RegEx to capture and replace exact matches, with expressions that might contain special characters
RegEx to capture and replace exact matches, with expressions that might contain special characters

Time:09-11

I am trying to create some sort of translation egine. I am given a mapping of attributes, and using this mapping I need to translate an expression.

For example, I have this mapping:

{
  "a": "A",
  "b[*]": "B[*]",
  "c": "C",
  "ac": "D"
}

And an example input might be (the rule is that each token can be followed by a ., it's actually a JSONPath):

a.b[*] should translate to A.B[*]

And each input can appear arbitraritly in the expression, for example I can have a mix: a.c.b[*] => A.C.B[*]

My solution was to create a list of Regexes out of this mapping, and looping that, searching and replacing the expression for each regex.

The problem was in inputs like that: ac => should have translated to D but instead, since there exist mapping for a and c, their regexes match and I get AC instead.

I thought to use word boundaries \b, but it didn't work well in cases there were special chars, like in the b[*] example, as it's not included in the word boundary.

I also thought to extend the boundary, but nothing worked as expected.

In the bottom line: is there a way to replace a stirng by another, considering that only a full match is valid, but an expression can be part of a JSONPath string?

CodePudding user response:

We can try building a regex alternation of the lookup keys. Then, use replace() with a callback function to make the replacements. As the comment by @Nick above mentions, the alternation should place longer substrings first.

var map = {
    "a": "A",
    "b[*]": "B[*]",
    "c": "C",
    "ac": "D"
};
var input = "a.c.b[*]";
var output = input.replace(/(ac|a|c|b\[\*\])/g, (x, y) => map[y]);
console.log(output);

This approach also avoids an ugly explicit loop.

  • Related