'How to use a RegExp literal as object key?

I would like to use create a object that contains regular expressions as the key value. I tried to use the following syntax:

var kv = {
    /key/g : "value"
};

But it fails according JavaScript lint:

SyntaxError: invalid property id

How can I fix it?

Update

Background: The reason why I want to do this is to implement a workaround that fixes wrong unicode in a HTTP API result. I know this is very hackish, but since I have no control over the API server code I think this is the best I can do.

Currently I implemented the mapping by having a keys array and a values array:

function fixUnicode(text) {

    var result = text;
    var keys = [];
    var values = [];
    keys.push(/é/g); values.push("é");
    keys.push(/è/g); values.push("è");
    keys.push(/ê/g); values.push("ê");
    keys.push(/ë/g); values.push("ë");
    keys.push(/à/g); values.push("à");
    keys.push(/ä/g); values.push("ä");
    keys.push(/â/g); values.push("â");
    keys.push(/ù/g); values.push("ù");
    keys.push(/û/g); values.push("û");
    keys.push(/ü/g); values.push("ü");
    keys.push(/ô/g); values.push("ô");
    keys.push(/ö/g); values.push("ö");
    keys.push(/î/g); values.push("î");
    keys.push(/ï/g); values.push("ï");
    keys.push(/ç/g); values.push("ç");

    for (var i = 0; i < keys.length; ++i) {
        result = result.replace(keys[i], values[i]);
    }
    return result;
}

But I want to implement to use a JavaScript object to map keys as values:

function fixUnicode(text) {

    var result = text;
    var keys = {
        /&Atilde;&copy;/g : "&eacute;",
        /&Atilde;&uml;/g :  "&egrave;"
        // etc...
    };

    for (var key in keys) {
        result = result.replace(key, keys[key]);
    }
    return result;
}


Solution 1:[1]

I think this question deserves an updated answer. Since ES6, a new type (standard built-in object) called Map was created to cover cases like this one among others.

A Map is very similar to an Object, except it allows any type as key.

Map.prototype.forEach() can then be used to loop over each key/value pair.

In your case, your function could now be:

function fixUnicode(text) {

    var result = text;
    var replaceMap = new Map();
    replaceMap.set(/&Atilde;&copy;/g, "&eacute;");
    replaceMap.set(/&Atilde;&uml;/g, "&egrave;");
    replaceMap.set(/&Atilde;&ordf;/g, "&ecirc;");
    replaceMap.set(/&Atilde;&laquo;/g, "&euml;");
    replaceMap.set(/&Atilde;&nbsp;/g, "&agrave;");
    replaceMap.set(/&Atilde;&curren;/g, "&auml;");
    replaceMap.set(/&Atilde;&cent;/g, "&acirc;");
    replaceMap.set(/&Atilde;&sup1;/g, "&ugrave;");
    replaceMap.set(/&Atilde;&raquo;/g, "&ucirc;");
    replaceMap.set(/&Atilde;&frac14;/g, "&uuml;");
    replaceMap.set(/&Atilde;&acute;/g, "&ocirc;");
    replaceMap.set(/&Atilde;&para;/g, "&ouml;");
    replaceMap.set(/&Atilde;&reg;/g, "&icirc;");
    replaceMap.set(/&Atilde;&macr;/g, "&iuml;");
    replaceMap.set(/&Atilde;&sect;/g, "&ccedil;");

    replaceMap.forEach(function (newString, old) {
      result = result.replace(old, newString);
    });

    return result;
}

You can read more about maps at MDN

Solution 2:[2]

Object keys cannot be RegExp objects. You must use a string or a valid ID. That being said, you could do something like this:

var kv = {
    "/key/g": "value"
};

I'm curious. Why do you want to do this?

EDIT: I am partially mistaken. RegExp objects can be used as keys, but not using the object literal syntax. See jmar777's answer.

Solution 3:[3]

You can also use an expression as a key by wrapping it in [] when creating an object:

var kv = {
    [/key/g] : "value"
};

Solution 4:[4]

Although this topic is old, it might be useful for reference to add another option.

While have regular expressions are not allowed as object property, they would be fine as a value.

Options

  • RegEx strings as object property and then convert back with new RegExp() (as mentioned previously)
    Consideration: have to run an extra constructor function & double escape special characters e.g. \\s+
  • Pairs of RegEx, replacement in arrays (as mentioned previously)
  • Swap property & value in the object i.e. replacement property and RegEx value

let str = 'Change this key and THIS KEY.';
const obj = {
  'value': /key/gi,
  'that': /this/gi
};
Object.entries(obj).forEach(([key, value]) => str = str.replace(value, key));
console.log(str);
// Change that value and that value.

Note:

  • Arrow function was added in ECMAScript 2015 aka ES6
  • Object.entries() was added in ECMAScript 2017 aka ES8
  • Object.keys() or for loop can be used for older browsers

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 cortopy
Solution 2
Solution 3 Klesun
Solution 4