来自正则表达式的模板字符串
Template string from regex
假设我有以下 URL 路径:
/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
.
我希望能够使用一组有限的正则表达式魔术来构建这样的字符串。
如何实现这样的模板引擎?
在 node.js 中,您只需定义两个不同的模板:
routes.route('/api/resource/:id')
.get....
routes.route('/api/resource/:id/relationships/:name')
.get...
但是,正如 trincot 提到的,如果您说明您使用什么框架来构建此功能,将会很有帮助。
您可以在 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);
这不会处理 ( )?
形式的嵌套括号。如果你需要,那么我建议有一个循环,首先解析所有这些可选表达式,直到剩下 none:
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);
实际上,我发现 path-to-regex 完全符合我的要求。
假设我有以下 URL 路径:
/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
.
我希望能够使用一组有限的正则表达式魔术来构建这样的字符串。
如何实现这样的模板引擎?
在 node.js 中,您只需定义两个不同的模板:
routes.route('/api/resource/:id')
.get....
routes.route('/api/resource/:id/relationships/:name')
.get...
但是,正如 trincot 提到的,如果您说明您使用什么框架来构建此功能,将会很有帮助。
您可以在 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);
这不会处理 ( )?
形式的嵌套括号。如果你需要,那么我建议有一个循环,首先解析所有这些可选表达式,直到剩下 none:
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);
实际上,我发现 path-to-regex 完全符合我的要求。