簡體   English   中英

"如何使用 RegExp 文字作為對象鍵?"

[英]How to use a RegExp literal as object key?

我想使用創建一個包含正則表達式作為鍵值的對象。 我嘗試使用以下語法:

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

這可以完成,但不能使用對象文字語法。 你需要這樣做:

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


編輯:這可能會使用一些解釋。 正如xanatos在下面評論的那樣,這里真正發生的是,在這種情況下,鍵/key/gtoString()來創建密鑰。 這一點很重要,因為它會對密鑰的唯一性產生影響。 考慮以下:

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

總之,我半害怕問你為什么需要這樣做,但假設你有你的理由,要小心,確保您了解什么是真正發生的事情:)


編輯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 

我認為這個問題值得更新答案。 從ES6開始,創建了一個名為Map的新類型(標准內置對象)來覆蓋像這樣的案例。

Map與Object非常相似,但它允許任何類型作為鍵。

然后可以使用Map.prototype.forEach()循環遍歷每個鍵/值對。

在您的情況下,您的功能現在可以是:

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

您可以在MDN上閱讀有關地圖的更多信息

對象鍵不能是RegExp對象。 您必須使用字符串或有效ID。 話雖這么說,你可以這樣做:

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

我很好奇。 你為什么要這樣做?

編輯:我有些錯誤。 RegExp對象可用作鍵,但不能使用對象文字語法。 請參閱jmar777的回答。

您還可以在創建對象時將表達式作為鍵包裝在[]

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

雖然這個主題很老,但它可能對添加另一個選項很有用。

雖然不允許將正則表達式作為對象屬性,但它們可以作為值。

選項<\/strong>

  • RegEx 字符串作為對象屬性,然后使用new RegExp()<\/code>轉換回來(如前所述)<\/em>
    考慮:必須運行額外的構造函數和雙重轉義特殊字符,例如\\\\s+<\/code><\/li>
  • 正則表達式對,數組替換(如前所述)<\/em><\/li>
  • 交換對象中的屬性和值,即替換屬性和 RegEx 值<\/li><\/ul>

     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.<\/code><\/pre>

    筆記:<\/strong>

      在 ECMAScript 2015 aka ES6 中添加了箭頭函數<\/li>
    • Object.entries()<\/code>被添加到 ECMAScript 2017 aka ES8<\/li>
    • Object.keys()<\/code>或for<\/code>循環可用於舊版瀏覽器<\/li><\/ul>"

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM