Javascript Regex для преобразования точечной нотации в скобочную нотацию - PullRequest
8 голосов
/ 22 мая 2010

Рассмотрим этот 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().

Ответы [ 3 ]

10 голосов
/ 22 мая 2010

Использование вспомогательной функции для итеративного доступа к свойствам:

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"

Попробуйте приведенный выше пример здесь .

Редактировать : Слегка элегантно , используя метод 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"

Попробуйте новый пример здесь .

0 голосов
/ 22 мая 2010

Вы можете взглянуть на тему Безошибочный глубокий доступ к свойствам? опубликовано на comp.lang.javascript - здесь представлены несколько подходов к тому, что вы хотите.

Для регулярного выражения все, что вам нужно, это /{.*?}/g

0 голосов
/ 22 мая 2010

Я не уверен, как интегрировать это в Javascript, но вот фрагмент кода Java, который использует регулярное выражение для выполнения необходимого преобразования:

    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].

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...