我们说我有以下网址路径:
/api/resource/:id
给定上下文对象{id: 1}
,路径将转换为/api/resource/1
。
现在我想构建一个更复杂的路径模板:
/api/resource/:id(/relationships/:name)?
此处relationships
成员是可选的,因此两个上下文都可以匹配:
{id: 1, name: 'rel1'}
将构建字符串/api/resource/1/relationships/rel1
。{id: 1}
仍应构建字符串/api/resource/1
。我希望能够使用一组有限的正则表达式魔术来构建这样的字符串。
如何实现这样的模板引擎?
答案 0 :(得分:1)
在node.js中,您只需定义两个不同的模板:
routes.route('/api/resource/:id')
.get....
routes.route('/api/resource/:id/relationships/:name')
.get...
但是,正如trincot所提到的,如果您说明了用于构建此功能的框架,将会很有帮助。
答案 1 :(得分:1)
您可以在replace
中使用带有回调函数的正则表达式:
function applyTemplate(template, obj) {
return template.replace(/\(([^()]*):(\w+)([^()]*)\)\?|:(\w+)/g,
function (match, before, name1, after, name2) {
let name = name1 || name2;
return name in obj ? (before||'') + obj[name] + (after||'') : '';
});
}
var result,
template = "/api/resource/:id(/relationships/:name)?";
result = applyTemplate(template, {id: 1, name: 'rel1'});
console.log(result);
result = applyTemplate(template, {id: 1});
console.log(result);

这不会处理( )?
形式的嵌套括号。如果你需要,那么我建议有一个循环首先解析所有这些可选表达式,直到没有剩下:
function applyTemplate(template, obj) {
var repeat = true;
while (repeat) {
repeat = false;
template = template.replace(/\(([^()]*):(\w+)([^()]*)\)\?/g, function (match, before, name, after) {
repeat = true;
return name in obj ? before + obj[name] + after : '';
});
}
// Now replace the non-optionals:
return template.replace(/:(\w+)/g, function (match, name) {
return obj[name] || '';
});
}
var result,
// Nested example
template = "/api/resource/:id(/relationships(/option/:option)?/:name)?";
result = applyTemplate(template, {id: 1, option: 'special', name: 'rel1'});
console.log(result);
result = applyTemplate(template, {id: 1, name: 'rel1'});
console.log(result);
result = applyTemplate(template, {id: 1});
console.log(result);

答案 2 :(得分:0)
实际上,我发现path-to-regex完全符合我的要求。