【问题标题】:Matching inner parentheses expressions in regex匹配正则表达式中的内括号表达式
【发布时间】:2023-04-06 20:40:02
【问题描述】:

我想在前端解析 Jinja 函数,如下所示:

{{ some_tag('firstarg', 'secondarg', 'thirdarg', 'fourtharg') }}

但我不知道会有多少参数。那我做了什么?我写了以下正则表达式:

{{\W*some_tag\W*\((['"](.*)['"],\W*){0,}['"](.*)['"]\)}}

但是,当我运行这个正则表达式时,我得到如下输出:

matches = regex.exec("{{ some_tag('firstarg', 'secondarg', 'thirdarg', 'fourtharg') }}")

matches:
  "{{ some_tag('firstarg', 'secondarg', 'thirdarg', 'fourtharg')}}",
  "'firstarg', 'secondarg', 'thirdarg'",
  "'firstarg', 'secondarg', 'thirdarg'",
  "'fourtharg'"

但这不是我想要的。我需要一种方法来匹配内括号,这样我就只有对应于firstarg、secondarg、thirdarg 和fourtharg 的变量。

我如何得到这个?

【问题讨论】:

  • 对于初学者来说,最内层括号的一个好的正则表达式是:/\(([^()]*)\)/,内容将在$1中

标签: javascript regex


【解决方案1】:

在 Javascript 中无法使用单个正则表达式来做到这一点。所以提取最里面的括号,没有第一个和最后一个引号,然后用', '分割第一个捕获组。

var s = "{{ some_tag('firstarg', 'secondarg', 'thirdarg', 'fourtharg') }}";
var re = /{{\s*(\w+)\s*\(\s*['"]((?:[^'"]*['"]\s*,\s*["'])*[^"']*)['"]\s*\)\s*}}/g;
var results = [];

while(m = re.exec(s)) {
    results.push({'func':m[1], 'param':m[2].split(/['"]\s*,\s*['"]/)})
}

console.log(results);

【讨论】:

    【解决方案2】:

    MDN 示例使用带有正则表达式的 find successive matches 循环。

    使用参数在单引号之间且不存在其他单引号的语法的示例:

    var re = /[^']*'([^']*)'/g  // remember single quoted match
    
    var str = "{{ some_tag('firstarg', 'secondarg', 'thirdarg', 'fourtharg') }}"
    
    var args = []; // args array
    var match;     // match array
    while(match = re.exec(str))
    {   args.push(match[1]);
    }
    
    args;  // [firstarg,secondarg,thirdarg,fourtharg]
    

    【讨论】:

      【解决方案3】:

      如果您需要确保在some_tag 之后获得这些参数,您可以在replace 方法中利用回调方法:

      var s = "{{ some_tag('firstarg', 'secondarg', 'thirdarg', 'fourtharg') }}";
      var res = [];
      s.replace(/some_tag\(([^()]*)\)/, function(m, g1) {
          var splt = g1.replace(/^'([\s\S]*)'$/, '$1').split(/',\s*'/).map(function (t) { res.push(t); });
      })
      document.body.innerHTML = JSON.stringify(res, 0, 4);
      

      您将整个 some_tag(...) 与 some_tag\(([^()]*)\) 匹配(或 - 如果值可以有 ( 和 ) - 与 some_tag\(([\s\S]*)\)\s*}}),然后删除初始和最终 's 并拆分带有' + 空格的第 1 组? + '.

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-02-13
        • 1970-01-01
        • 2011-07-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-08-03
        相关资源
        最近更新 更多