用 javascript 对象替换字符串值

问题描述 投票:0回答:5

我目前正在为 NodeJs 制作一个小模块。为此我需要一点帮助。

我会这样说。 我有一个带字符串的变量。它包含一个字符串 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" });

javascript regex node.js object template-engine
5个回答
11
投票

您可以使用正则表达式使用简单的模板函数,

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

详情请看这里

编辑

实际上正如torazaburo在评论中提到的,它可以重构为

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

jsfiddle

希望这有帮助


8
投票

此解决方案使用 模板字符串 来完成您想要的一切。

此解决方案的优点是,与另一个答案中提出的基于正则表达式的天真滚动模板替换策略相比,它支持任意计算,如

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"

1
投票

由于您使用的是 ES6 模板字符串,因此您可以使用名为“标记模板字符串”的功能。使用标记的模板字符串,您可以修改模板字符串的输出。您可以通过在模板字符串前面放置一个“标签”来创建标记模板字符串,“标签”是对方法的引用,该方法将接收列表中的字符串部分作为第一个参数,并将插值值作为剩余参数。模板字符串的 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

上运行代码示例


1
投票

String.prototype.replaceByObject = function(obj) { return this.replace(RegExp(Object.keys(obj).join('|'), 'g'), function(val) { return obj[val]; }); }

像这样使用它

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



0
投票
您可以通过调用以下方式使用“标签”:

<div DataTemp="${d1}"></div> <div DataTemp="${d2}"></div> <div DataTemp="${d3}"></div> <div DataTemp="${d3}+ +${d1}"></div> <div DataTemp="${d3}/${d1}"></div> <div DataTemp="${d4}\${d1}"></div> <div DataTemp="(${d5}\${d1})"></div> <div DataTemp="(${d3}\${d1})"></div>

有数据
var data={d1:'t1',d2:'t2',d3:'t3'}

    

© www.soinside.com 2019 - 2024. All rights reserved.