我想写一个函数,如:
function extract(template, example){
//some magic
return obj;
}
给出如下输入:
var template = "/some/path/{param_one}/{another_param}/etc?arg1={value}";
var example = "/some/path/foo/bar/etc?arg1=baz";
会返回此对象:
{param_one: "foo", another_param: "bar", value: "baz"}
我无法控制模板或示例(例如,我无法将模板更改为具有命名捕获组的正则表达式)。我可以安全地假设给定的示例将与模板匹配。
首先,我能够用这个提取密钥:
var re = /\{(.+?)\}/g;
var match;
do {
match = re.exec(template)
if (match) {
console.log(match[1]);
}
} while (match);
答案 0 :(得分:1)
我使用正则表达式并替换来解决:
function extract(template, example){
//some magic
var re = /(?:([^\{]*)\{([^\}]*)\})/g;
var result = example;
var params = [];
var match, values, obj = {};
do {
match = re.exec(template)
if (match) {
result = result.replace(match[1], '|');
params.push(match[2]);
}
} while (match);
values = result.split('|');
for(var i=0;i < params.length; i++) {
obj[params[i]] = values[i+1];
}
return obj;
}
首先,它使用params部分和文本部分使用正则表达式,然后用|
替换所有文本部分并将存储键存储到params数组。
最后,它循环遍历params数组并匹配从上面分割的值
希望这个帮助
答案 1 :(得分:0)
我会把它分成两部分 - 构建一个模板对象,然后使用该模板对象来解析你的字符串。以下函数buildTemplate(pattern)
返回模板对象。然后,您可以使用此对象根据需要解析任意数量的字符串,例如buildTemplate(pattern).parse(string)
甚至var parser = buildTemplate(pattern); var parameters = parser.parse(string);
。
function buildTemplate(pattern) {
return (function(pattern) {
function splitString(string) {
return string.split(/[/?&]+/);
}
var glob = {};
glob.parts = splitString(pattern).map(function(part) {
var trimmedPart = part.replace(/^\{|\}$/g, '');
var isLiteral = part.length !== trimmedPart.length + 2;
return {
isLiteral: isLiteral,
value: isLiteral ? part : trimmedPart:
};
});
glob.parse = function(string) {
var stringParts = splitString(string);
if (stringParts.length !== glob.parts.length) {
return null;
}
var params = {};
for (var i = 0; i < stringParts.length; i++) {
if (blob.parts[i].isLiteral) {
if (blob.parts[i].value !== stringParts[i]) {
return null;
}
} else {
params[blob.parts[i].value] = stringParts[i];
}
}
return params;
}
return glob;
})(pattern);
}
注意:此代码完全 未经测试 。如果某些内容无效,请告诉我。