正则表达式提取数组索引

时间:2016-08-27 14:19:51

标签: javascript regex

我仍然很难理解正则表达式...: - /

给出类似字符串(类似JavaScript的表达式)......

  • foo[0]
  • foo[4][2]
  • foo[4][2][234523][3]

...我正在尝试解构正则表达式中的索引,所以我有

  • 变量的名称:foo
  • 单个索引:最后一个示例中的fox示例422345233

虽然接受无效的语法,如

  • foo[23]bar[55]
  • foo[123]bar
  • [123]bla
  • foo[urrrr]

最好还是忽略foo [13]foo[ 123 ]这样的空格,但这并不重要。

正则表达式可以吗?

我能够用var matches = s.match(/\[([0-9]?)\]/g);提取括号,但是包含结果中的括号,缺少变量名称(可以绕过它),也不会像上面描述的那样尊重边缘情况。

3 个答案:

答案 0 :(得分:1)

您必须使用循环来提取多个匹配项。这是一种方式:

function run(string) {
  var match;
  if(match = string.match(/^([^[]+)\s*(\[\s*(\d+)\s*\]\s*)+\s*$/)) {
    var variable = match[1], indices = [];
    var re = /\[\s*(\d+)\s*\]/g;
    while(match = re.exec(string)) {
      indices.push(+match[1]);
    }
    return { variable: variable, indices: indices };
  } else {
    return null;
  }
}

var strings = [
  "foo[0]",
  "foo[4][2]",
  "foo[4][2][234523][3]",
  "foo [13]",
  "foo[ 123 ]",
  "foo[1] [2]",
  "foo$;bar%[1]",
  // The following are invalid
  "foo[23]bar[55]",
  "foo[123]bar",
  "[123]bla",
  "foo[urrrr]",
];

// Demo
strings.forEach(function(string) {
  document.write("<pre>" + JSON.stringify(run(string), null, 4) + "</pre>");
});

答案 1 :(得分:0)

那是not possible

您可以测试它是否是正确的声明,并且只要您知道有多少索引就可以选择它们,但是无法使用javascript .exec多次捕获组。

然而,语言是正常的。所以就是这样:

^([a-zA-Z][a-zA-Z_0-9]*)(\[[0-9]*\])*

第一组将匹配变量,第二组(*量词0-n次)与索引匹配。

因此,如果你想这样做,我建议使用另一种解析方法:

function parse(str) {
  let idx = 0;
  while(str[idx+1] != '[') {
    idx++;
  }

  let name = str.substr(0, idx+1);


  let indices = [];
  while(str[idx+1] == '[') {
    idx++;
    let startIdx = idx;
    while(str[idx+1] != ']') {
      idx ++;
    }
    console.log(idx);
    indices.push(str.substr(startIdx+1, idx-startIdx));
    idx++;
  }

  return {name,indices};
}

答案 2 :(得分:0)

以下是获得所需数组的2步正则表达式的小型ES6版本:

&#13;
&#13;
function interpret(s) {
    return (/^(\w+)\s*((?:\[\s*\d+\s*\]\s*)*)$/.exec(s) || [,null]).slice(1).reduce(
        (fun, args) => [fun].concat(args.match(/\d+/g))); 
}

var s = 'foo[4][2][234523][3]';
var result = interpret(s);
console.log(result);
&#13;
&#13;
&#13;

首先通过exec()获取2个主要部分,它返回完整匹配,函数名称和数组中的其余部分(包含3个元素)。然后用slice(1)忽略这三个中的第一个。另外两个传递给reduce

reduce回调只会被调用一次,因为没有提供初始值。

这很方便,因为它实际上意味着回调将两部分作为其两个参数。它应用第二个正则表达式来拆分索引字符串,并返回最终数组。

当原始匹配失败时,|| [,null]会处理这种情况:它会确保reduce[null]采取行动,从而返回null