javascript 如何使用 RegExp 文字作为对象键?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7365027/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-25 23:52:31  来源:igfitidea点击:

How to use a RegExp literal as object key?

javascript

提问by StackedCrooked

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:

但它根据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.

背景:我之所以要这样做是为了实施一种解决方法来修复 HTTP API 结果中错误的 unicode。我知道这是非常骇人听闻的,但由于我无法控制 API 服务器代码,我认为这是我能做的最好的事情。

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:

但我想实现使用 JavaScript 对象将键映射为值:

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;
}

回答by jmar777

This can be done, but not using object literal syntax. You'll need to do it like this:

这可以完成,但不能使用对象字面量语法。你需要这样做:

var kv = {};
kv[/key/g] = "value";
console.log(kv[/key/g]); // "value"



编辑:这可能需要一些解释。正如 xanatos 在下面评论的那样,这里真正发生的事情是,/key/g/key/g在这种情况下,关键是toString()toString()要创建密钥。了解这一点很重要,因为它会影响密钥的唯一性。考虑以下:

var x = {},
    reg = /foo/;

x[reg] = 'bar';
console.log(x[reg]); // "bar"
console.log(x[reg.toString()]); // "bar"
console.log(x['/foo/']); // "bar'

In summary, I'm semi-scared to ask whyyou need to do this, but assuming you have your reasons, be careful and make sure you understand whatis really happening :)

总之,我半吓得问为什么你需要做到这一点,但假设你有你的理由,要小心,确保您了解什么是真正发生的事情:)



编辑 2:因此,为了回应您更新的问题,您应该能够实现与您想要的非常接近的东西。只要将正则表达式用引号括起来,就可以使用对象字面量语法。不幸的是,这意味着您必须手动从该键中重建一个实际的 RegExp 对象。例如:

var result = "abcdef",
    replacements = {
        "/a/g": "FOO",
        "/d/i": "BAR"
    };

for (var key in replacements) {
    var parts = key.split('/');
    result = result.replace(new RegExp(parts[1], parts[2]), replacements[key]);
}

console.log(result); //FOObcBARef



编辑 3:因为,为什么不呢。我一直坚持让您的对象字面量语法起作用,以至于我没有考虑到您永远不需要实际查找模式本身的替换这一事实(即,根本不需要对象键)。这是使用不需要 RegExp 重建的数组的更有效方法:

var result = "abcdef",
    replacements = [
        [/a/g, "FOO"],
        [/d/i, "BAR"]
    ];

for (var i = 0, len = replacements.length; i < len; i++) {
    var replacement = replacements[i];
    result = result.replace(replacement[0], replacement[1]);
}

console.log(result); //FOObcBARef



编辑 4:因为我很无聊而且我喜欢这个问题。这是忍者版本:

var result = "abcdef",
    replacements = [
        [/a/g, "FOO"],
        [/d/i, "BAR"]
    ], r;

while ((r = replacements.shift()) && (result = String.prototype.replace.apply(result, r))) {}

console.log(result); //FOObcBARef

回答by cortopy

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.

我认为这个问题值得更新的答案。自 ES6 以来,创建了一种名为 Map 的新类型(标准内置对象)以涵盖诸如此类的情况。

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

Map 与 Object 非常相似,除了它允许任何类型作为键。

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

然后可以使用 Map.prototype.forEach() 循环遍历每个键/值对。

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

你可以在MDN阅读更多关于地图的信息

回答by FishBasketGordo

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

对象键不能是 RegExp 对象。您必须使用字符串或有效 ID。话虽如此,你可以这样做:

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.

编辑:我有部分错误。RegExp 对象可以用作键,但不能使用对象字面量语法。请参阅 jmar777 的回答。

回答by Klesun

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

您还可以通过在[]创建对象时将表达式包装在其中来使用表达式作为键:

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