Javascript 模板和占位符算法
首先是一个快速定义:)Javascript 模板和占位符算法,javascript,algorithm,templates,placeholder,Javascript,Algorithm,Templates,Placeholder,首先是一个快速定义:) 模板-可能包含占位符的字符串(例如:“hello[name]”) 占位符-方括号中的子字符串(例如“hello[name]:”中的“name”) 属性映射-以字符串作为值的有效对象 我需要编写一个代码,用属性映射中的匹配值替换占位符(以及括号) 例如: 对于以下属性映射: { "name":"world", "my":"beautiful", "a":"[b]", "b":"c", "c":"my" } 预期成果: “你好名
- 模板-可能包含占位符的字符串(例如:“hello[name]”)
- 占位符-方括号中的子字符串(例如“hello[name]:”中的“name”)
- 属性映射-以字符串作为值的有效对象
{
"name":"world",
"my":"beautiful",
"a":"[b]",
"b":"c",
"c":"my"
}
预期成果:
- “你好名字”->“你好名字”
- “你好[姓名]”->“你好,世界”
- “[b]”->“c”
- “[a]”->“c”(因为[a]->[b]->[c])
- “[[b]]”->“我的”(因为[[b]]->[c]->我的)
- “你好[我的][名字]”->“你好,美丽的世界”
substituteRegExp
的作用):
更新:我做了一些分析来比较这两种解决方案(JSFIDLE at,我还使用了Firebug)。虽然@chris解决方案对于小字符串更快(不需要解析正则表达式等),但该解决方案对于大字符串(以数千个字符的顺序)的性能要好得多。我并没有比较不同大小的房产地图,但我预计会有更大的差异
理论上,此解决方案具有运行时O(kn),其中k是占位符嵌套的深度,n是字符串的长度(假设字典/哈希查找需要恒定的时间),而@chris的解决方案是O(knm),其中m是属性映射中的项数。当然,所有这些都只与大型输入相关。如果您熟悉.NET的
String.Format
,那么您应该看看。它也支持数字格式,就像String.Format
下面是一个如何使用它的示例:
var result = String.Format("Hello {my} {name}", map);
但是,执行递归模板需要一些修改。如果有循环,如a->[b]和b->[a],会发生什么?此外,是否所有决策都是强制的(即,没有键映射到多个值?)当然,忽略循环。将地图对象视为ValIdxCelt!这正是我所需要的!非常感谢谢谢你,这真是太详细了!
function substituteRegExp(string, regexp, f) {
// substitute all matches of regexp in string with the value
// returned by f given a match and the corresponding group values
var found;
var lastIndex = 0;
var result = "";
while (found = regexp.exec(string)) {
var subst = f.apply(this, found);
result += string.slice(lastIndex, found.index) + subst;
lastIndex = found.index + found[0].length;
}
result += string.slice(lastIndex);
return result;
}
function templateReplace(string, values) {
// repeatedly substitute [key] placeholders in string by values[key]
var placeholder = /\[([a-zA-Z0-9]+)\]/g;
while (true) {
var newString = substituteRegExp(string, placeholder, function(match, key) {
return values[key];
});
if (newString == string)
break;
string = newString;
}
return string;
}
alert(templateReplace("hello [[b]] [my] [name]", {
"name":"world",
"my":"beautiful",
"a":"[b]",
"b":"c",
"c":"my"
})); // -> "hello my beautiful world"
var result = String.Format("Hello {my} {name}", map);