Javascript 从给定简单模板的示例字符串中提取值

Javascript 从给定简单模板的示例字符串中提取值,javascript,Javascript,我想写一个函数,例如: 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_pa

我想写一个函数,例如:

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);

我将把它分成两部分——构建一个模板对象,然后使用该模板对象解析字符串。下面的函数
buildTemplate(pattern)
返回一个模板对象。然后,您可以使用此对象根据需要解析任意多个字符串,例如
buildTemplate(pattern).parse(string)
甚至
var parser=buildTemplate(pattern);var参数=parser.parse(字符串)

函数构建模板(模式){
返回(函数(模式){
函数拆分字符串(字符串){
返回字符串.split(/[/?&]+/);
}
var glob={};
glob.parts=splitString(pattern).map(函数(part){
var trimmedPart=part.replace(/^\{124;\}$/g',);
var isLiteral=part.length!==trimmedPart.length+2;
返回{
isLiteral:isLiteral,
值:isLiteral?零件:trimmedPart:
};
});
glob.parse=函数(字符串){
var stringParts=splitString(字符串);
if(stringParts.length!==全局parts.length){
返回null;
}
var params={};
对于(var i=0;i

注意:此代码完全未经测试。如果某项功能无法正常工作,请通知我。

我使用regex和replace来解决:

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;
}
函数提取(模板,示例){
//一些魔法
变量re=/(?:([^\{]*)\{([^\}]*)\})/g;
var结果=示例;
var参数=[];
变量匹配,值,obj={};
做{
match=re.exec(模板)
如果(匹配){
结果=结果。替换(匹配[1],“|”);
参数推送(匹配[2]);
}
}while(匹配);
values=result.split(“|”);
对于(变量i=0;i
首先,它使用regex获取参数部分和文本部分,然后用
|
替换所有文本部分,并将密钥存储到params数组

最后,它循环遍历params数组并匹配从上面拆分的值


希望此帮助

问题没有明确说明。
template=“{param_one}{param_two}”的结果是什么;示例=“abc”?或
template=“{param_one}/{param_two}”;示例=“///”
?如果您的输入总是url路径+查询,那么它将是可解的。@leum,您是对的。您可以假设它始终是一个路径和查询,并且两个模板变量始终至少由
/
&
分隔。虽然也应接受以下内容:
{param_a}/前缀{param_b}/
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;
}