Я изо всех сил пытаюсь понять, как заставить это регулярное выражение работать без цикла. Вот код, который работает:

var template = {name: "Oscar", anotherName: "your twin", hello: 'world'}
var str = "Hello, {{name}} I'm {{anotherName}}. Hello to the {{hello}}"

Object.keys(template).forEach(function (keyName) {
    pattern = new RegExp('{{' + keyName + '}}', 'g');
    str = str.replace(pattern, template[keyName]);
})

// => str "Hello, Oscar I'm your twin. Hello to the world"

Что мне не нравится в этом коде, так это то, что он находится в цикле, генерирующем регулярное выражение, когда я чувствую, что регулярное выражение должно обрабатывать этот вариант использования. Однако мое регулярное выражение всегда соответствует только последнему элементу. Я делал регулярное выражение вроде str.match(/({{.}})/gi), но тогда совпадал только {{hello}}.

Предпочтительно я хотел бы сделать что-то, где я мог бы получить все совпадения в массиве, а затем сопоставить массив, например matchesFromRegex.map(match => template[match]).join('')

Кроме того, я использую обычную среду JS, поэтому .matchAll (который не поддерживается в IE) не будет работать.

0
Oscar Godson 24 Июн 2020 в 04:14

1 ответ

Лучший ответ

В строке RegEx { имеет особое значение (он позволяет вам установить мощность совпадения, например \d{5} для пяти цифр).

Вместо этого используйте new RegExp('\\{\\{' + keyName + '}}', 'g');. Двойная обратная косая черта в JavaScript создаст обратную косую черту, которая будет экранировать символ {.

Если вы хотите избежать цикла, вы можете использовать вместо него функциональную версию replace:

const pattern = /\{\{([^}]*)}}/g;
str.replace(pattern, (_, key) => template[key]);

Чтобы разбить это, pattern имеет группу захвата (части в ()). Функция String.prototype.replace может позволить вам предоставить функцию для выполнения замен, которая будет передавать ваши результаты соответствия.

2
Jacob 24 Июн 2020 в 01:18