-1

I'm trying to match a bunch of abbreviations that I'll need to extract or change in a list of data points. I believe I have a working solution but I would love to hear thoughts from more experienced regex users. The code will be written in JavaScript. Thanks for your help!

\b([CMKLPR]|PW|CCR|CS|CW|FG|G|Int|Jct|NOBO|NTH|P|PH|PO|PT|RG|Rx|SF|SOBO|SP|SR|TH|W|WMA|WMD)\b

Sample of the abbreviations (There are more)

C Camping

CCW Counter-clockwise

CG Campground (fee & potable water, unless otherwise indicated)

CR County Road

CS Convenience Store

CW Clockwise

FG Fire grate or grill

P Parking

G Grocery

This is what the data point strings look like

John Stretch Park at bicycle/pedestrian bridge. PW, R, PT, Day P, PH. NO CAMPING.

Edit To help clarify what I'm trying to do ....

I need to change this:

  {
      "Description": "Jct with 0.1-mile blue-blaze to Three Lakes Camp. C, RG, PT, W from pump.",
  }

To Something Like this:

{
    "Description": "Jct with 0.1-mile blue-blaze to Three Lakes Camp.",
    "Amenities": [
        {
            "Title": "Camping",
            "Icon": "camping.png"
        },
        {
            "Title": "Register",
            "Icon": "register.png"
        },
        {
            "Title": "Picnic Table",
            "Icon": "picnic.png"
        },
        {
            "Title": "Water",
            "Icon": "water.png"
        }
    ]
}
  • Do you think regex here is the best solution? Simple string replace wouldn't be better? – Magiczne Aug 23 '20 at 14:00
  • I'm not sure, I'm a novice developer at best, maybe I'm approaching this wrong? Some of the abbreviations will be removed from the string and used to create an array of amenities at that particular point. For example If the data point has a 'C' & 'G' I want to remove those from the string and add it to it's own array within that point. – Thomas Smith Aug 23 '20 at 14:15
  • Ok, so probably regex will be better but I would think maybe of generating it on the fly – Magiczne Aug 23 '20 at 14:20
  • I didn't mean to change the question, I'm not looking for a complete solution, I'm just trying to figure out if I'm on the right path. Thank you everyone for your help. – Thomas Smith Aug 23 '20 at 14:43

2 Answers2

1

The idea of such a regular expression is fine. You could build the expression dynamically, based on an object with key/value pairs defining the mapping. Then use the callback argument of replace to find the relevant replacement string.

let map = {
  C: "Camping",
  CCW: "Counter-clockwise",
  CG: "Campground (fee & potable water, unless otherwise indicated)",
  CR: "County Road",
  CS: "Convenience Store",
  CW: "Clockwise",
  FG: "Fire grate or grill",
  P: "Parking",
  G: "Grocery",
};

let regex = RegExp("\\b(" + Object.keys(map).join("|") + ")\\b", "g");

let input = "G, P, FG, and CS, on this C.";
let result = input.replace(regex, m => map[m]);
console.log(result);

Note: If the abbreviations have any characters that have a special meaning in a regular expression, make sure to escape such characters properly in the mapper object, or use a dynamic solution like here.

If the mapping is a constant, and the input varies, you could make a specific function for a given mapping, and then use that for processing different inputs. I include here also the escaping:

function createReplacer(map) {
  let escaper = str => str.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
  let regex = RegExp("\\b(" + Object.keys(map).map(escaper).join("|") + ")\\b", "g");
  return str => str.replace(regex, m => map[m]);
}

// demo
let replacer = createReplacer({
  C: "Camping",
  CCW: "Counter-clockwise",
  CG: "Campground (fee & potable water, unless otherwise indicated)",
  CR: "County Road",
  CS: "Convenience Store",
  CW: "Clockwise",
  FG: "Fire grate or grill",
  P: "Parking",
  G: "Grocery",
  "A-F": "A-frame tents",
});

let input = "G, P, FG, and CS, on this C. A-F allowed";
console.log(replacer(input));
trincot
  • 317,000
  • 35
  • 244
  • 286
  • This is really close to the end result I was thinking, I do want to build the string dynamically, thank you! – Thomas Smith Aug 23 '20 at 14:42
  • Added a bit more. You write "really close"... what is missing? – trincot Aug 23 '20 at 15:18
  • 1
    I meant in the overall context of my problem, there is more to figure out, beyond the regex. I'm an extremely new developer so it also served as a personal confirmation. This was close to how I was going to approach it using key value pairs and dynamically build the regex but I wasn't sure where to start, I do now thank you!! – Thomas Smith Aug 23 '20 at 17:52
0

Ciao, you could use RegExp.exec to find substring in your string and replace it with another string that not match with your regex. Like:

let str = "John Stretch Park at bicycle/pedestrian bridge. PW, R, PT, Day P, PH. NO CAMPING.";

var re  = new RegExp(/\b([CMKLPR]|PW|CCR|CS|CW|FG|G|Int|Jct|NOBO|NTH|P|PH|PO|PT|RG|Rx|SF|SOBO|SP|SR|TH|W|WMA|WMD)\b/g);

let result = re.exec(str)
while(result !== null)
{
  console.log(result[0])
  str = str.replace(result[0], "_") // replace with something
  result = re.exec(str)
}
Giovanni Esposito
  • 10,696
  • 1
  • 14
  • 30