【问题标题】:Javascript Regex to convert dot notation to bracket notationJavascript正则表达式将点符号转换为括号符号
【发布时间】:2010-05-22 04:51:52
【问题描述】:

考虑这个javascript:

var values = {
    name: "Joe Smith",
    location: {
        city: "Los Angeles",
        state: "California"
    }
}

var string = "{name} is currently in {location.city}, {location.state}";

var out = string.replace(/{([\w\.]+)}/g, function(wholematch,firstmatch) {
    return typeof values[firstmatch] !== 'undefined' ? 
        values[firstmatch] : wholematch;
});

这将输出以下内容:

Joe Smith is currently in {location.city}, {location.state}

但我想输出以下内容:

Joe Smith is currently in Los Angeles, California

我正在寻找一种将字符串中大括号之间的多级点表示法转换为与括号表示法一起使用的多个参数的好方法,如下所示:

values[first][second][third][etc]

本质上,对于这个例子,我试图找出我需要什么正则表达式字符串和函数,最终得到相当于:

out = values[name] + " is currently in " + values["location"]["city"] +
    values["location"]["state"];

注意:我不想使用eval()

【问题讨论】:

  • 刚注意到一个错字。将var joe 重命名为var values
  • 另一个类似的问题有@J-P 对这里的答案的替代解决方案。它看起来相当优雅:stackoverflow.com/questions/3344392/…

标签: javascript regex


【解决方案1】:

使用辅助函数迭代访问属性:

function getNestedValue(obj, prop) {
  var value, props = prop.split('.'); // split property names

  for (var i = 0; i < props.length; i++) {
    if (typeof obj != "undefined") {
      obj = obj[props[i]]; // go next level
    }
  }
  return obj;
}

var string = "{name} is currently in {location.city}, {location.state}";

var out = string.replace(/{([^}]+)}/g, function(wholematch,firstmatch) {
  var value = getNestedValue(joe, firstmatch);
  return typeof value !== 'undefined' ? value : wholematch;
});
// "Joe Smith is currently in Los Angeles, California"

试试上面的例子here

编辑:有点优雅,使用 Array.prototype.reduce 方法,新 ECMAScript 第 5 版标准的一部分:

function replace(str, obj) {
  return str.replace(/{([^}]+)}/g, function(wholematch,firstmatch) {
    var value = firstmatch.split('.').reduce(function (a, b) {
      return a[b];
    }, obj);
    return typeof value !== 'undefined' ? value : wholematch;
  });
}

replace("{name} is currently in {location.city}, {location.state}", values);
// "Joe Smith is currently in Los Angeles, California"

试试新的例子here

【讨论】:

  • @CMS:很好,很管用!但是,它似乎不像基于正则表达式的解决方案那样优雅,我想相信有一种正则表达式方法可以做到这一点。再说一次,也许追求正则表达式解决方案是浪费时间。
  • @CMS:您的正则表达式不允许大括号之间的任何内容吗?如果我想将值限制为有效的 javascript 变量名称 [a-zA-Z0-9_\.],最好使用 /{([\w\.]+)}/g 吗?实际上,这将允许在开始时有一个句点,这是不允许的,但它很接近。哦,是的,我想我也需要包含$
  • @Tauren,对,它有点宽容,我不太在意,因为当您使用括号表示法访问属性(或在对象文字中使用字符串)时,没有任何限制,即obj["3.xx\u0009"] ...
  • @CMS:非常酷!太糟糕了reduce 还没有得到普遍支持,但我猜Array.prototype.reduce 并没有那么大。
  • @Tauren,不大,有标准兼容版本可用here... IE 是唯一缺少此标准方法的主流浏览器...
【解决方案2】:

我不确定如何将它集成到 Javascript 中,但这里有一个 Java sn-p,它使用正则表达式来完成您需要的转换:

    String[] tests = {
        "{name}",
        "{location.city}",
        "{location.state.zip.bleh}",
    };
    for (String test : tests) {
        System.out.println(test.replaceAll("\\{?(\\w+).?", "[$1]"));
    }

打印出来:

[name]
[location][city]
[location][state][zip][bleh]

基本上它将所有出现的\{?(\w+).? 替换为[$1]

【讨论】:

  • 嗯,很有趣。但是,即使我在 JS 中使用它,我想我最终会得到一个字符串,我需要 eval,我想避免这种情况。
【解决方案3】:

您可以查看在 comp.lang.javascript 上发布的主题 Error-free deep property access? - 这提供了几种方法来做您想做的事。

对于正则表达式,您只需要/{.*?}/g

【讨论】:

    猜你喜欢
    • 2020-10-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-04
    • 1970-01-01
    • 1970-01-01
    • 2019-01-05
    相关资源
    最近更新 更多