2016-01-11 2 views
2

В настоящее время я создаю небольшой модуль для NodeJs. Для чего мне нужна небольшая помощь.Заменить строковое значение на объект javascript

Скажу так: У меня есть переменная со строкой. Он содержит значение строки html. Теперь мне нужно заменить $(title) что-то вроде этого с моим объектом { "title" : "my title" }. Это можно расширить до всего, что предоставляет пользователь. Это текущий код. Я думаю, что мне нужен RegEx для этого. Можете ли вы, ребята, помочь мне с этим?

var html = `<!DOCTYPE html> 
 
<html lang="en"> 
 
<head> 
 
    <meta charset="UTF-8"> 
 
    <title>Document $(title)</title> 
 
</head> 
 
<body> 
 

 
    <h1>Test file, $(text)</h1> 
 

 
</body> 
 
</html>`; 
 

 
function replacer(html, replace) { 
 
    // i need a regex to replace these data 
 
    //return replacedData; 
 
} 
 

 
replacer(html, { "title" : "my title", "text" : "text is this" });

+0

Поскольку вы используете узел, используйте один из многих компетентных шаблонных движков там, например, EJS. –

ответ

2

Вы можете использовать простую функцию шаблона с помощью регулярных выражений,

var replacer = function(tpl, data) { 
    var re = /\$\(([^\)]+)?\)/g, match; 
    while(match = re.exec(tpl)) { 
    tpl = tpl.replace(match[0], data[match[1]]) 
    re.lastIndex = 0; 
    } 
    return tpl; 
} 

использование как

var result = replacer(html, { "title" : "my title", "text" : "text is this" }); 

jsfiddle

detail here

EDIT

На самом деле, как torazaburo упоминалось в комментарии, он может быть переработан в

var replacer = function(tpl, data) { 
    return tpl.replace(/\$\(([^\)]+)?\)/g, function($1, $2) { return data[$2]; }); 
} 

jsfiddle

надеюсь, что это помогает

+0

спасибо soo много. это хорошо работает: D –

+0

приветствуется :) – shakib

+0

Ну, конечно, но это не сработает с такими вещами, как '$ (title.toUpperCase())'. –

1

Поскольку вы используете ES6 шаблон строки вы можете использовать функцию под названием 'tagged template strings'. Используя помеченные строки шаблона, вы можете изменить вывод строки шаблона. Вы создаете помеченную строку шаблона, поместив «тег» перед строкой шаблона, «тег» - это ссылка на метод, который получит строковые части в списке в качестве первого аргумента и значения интерполяции в качестве остальных аргументов. Страница MDN на строках шаблона уже представлен пример шаблона строки «тегов», который можно использовать:

function template(strings, ...keys) { 
    return (function(...values) { 
    var dict = values[values.length - 1] || {}; 
    var result = [strings[0]]; 
    keys.forEach(function(key, i) { 
     var value = Number.isInteger(key) ? values[key] : dict[key]; 
     result.push(value, strings[i + 1]); 
    }); 
    return result.join(''); 
}); 
} 

Вы используете «тег» по телефону:

var tagged = template`<!DOCTYPE html> 
<html lang="en"> 
<head> 
    <meta charset="UTF-8"> 
    <title>Document ${'title'}</title> 
</head> 
<body> 

    <h1>Test file, ${'text'}</h1> 

</body> 
</html>`; 

Обратите внимание, что интерполяция переменных использует синтаксис ${'key'} вместо $(key). Теперь вы можете вызвать произведенную функцию, чтобы получить желаемый результат:

tagged({ "title" : "my title", "text" : "text is this" }); 

Выполнить пример кода на es6console

+0

Я использую потоки NodeJs для чтения html-файла. могу ли я использовать его с этим? –

+0

NodeJS 5.0 и 4.0 поддерживает строки шаблонов (при запуске узла с --harmony), но вы не можете преобразовать входные потоки в строки шаблона. Они должны быть построены с помощью 'ticks – Matthisk

+0

ok, я попробую: D –

1

Это решение использует template strings, чтобы делать все, что вы хотите.

Это решение имеет то преимущество, что, в отличие от наивного рулонной своего собственного регулярного выражения на основе шаблона стратегии замены, как было предложено в другой ответ, он поддерживает произвольные расчеты, как и в

replacer("My name is ${name.toUpperCase()}", {name: "Bob"}); 

В этой версии из replacer мы используем new Function для создания функции, которая принимает свойства объекта в качестве параметров и возвращает шаблон, переданный в качестве строки шаблона. Затем мы вызываем эту функцию со значениями свойств объекта.

function replacer(template, obj) { 
    var keys = Object.keys(obj); 
    var func = Function(...keys, "return `" + template + "`;"); 

    return func(...keys.map(k => obj[k])); 
} 

Определим шаблон, используя ${} замен (вместо $()), но избежать, как \${, чтобы предотвратить оценку. (Мы могли бы просто указать его как обычный строковый литерал, но затем потеряли бы многострочные возможности).

var html = `<!DOCTYPE html> 
<html lang="en"> 
<head> 
    <meta charset="UTF-8"> 
    <title>Document \${title}</title> <!-- escape $ --> 
</head> 
<body> 

    <h1>Test file, \${text}</h1>  <!-- escape $ --> 

</body> 
</html>`; 

Теперь все работает именно так, как вы хотите:

replacer(html, { "title" : "my title", "text" : "text is this" }); 

Простой пример:

> replacer("My name is ${name}", {name: "Bob"}) 
< "My name is Bob" 

Вот пример вычисляемых полей:

> replacer("My name is ${name.toUpperCase()}", {name: "Bob"}) 
< "My name is BOB" 

или даже

> replacer("My name is ${last ? lastName : firstName}", 
    {lastName: "Jones", firstName: "Bob", last: true}) 
< "My name is Jones" 
Смежные вопросы