如何匹配平衡的非空括号?

时间:2016-02-22 12:17:50

标签: regex string pcre

使用正则表达式,给定以下文本,如何匹配平衡方括号之间的内容,但仅当它不为空时?

{
    "key1": [
        {
            "key2": "",
            "key3": "",
            "key4": "",
            "key5": []
        }
    ],
    "key6": [
        {
            "key7": "",
            "key8": "",
            "key9": [
                {
                    "key10": "",
                    "key11": "",
                    "key12": "",
                    "key13": []
                }
            ],
            "key14": ""
        }
    ],
    "key15": [],
    "key16": []
}

/\[([\s\S]+)\]/g:这是我的尝试,我的想法是我匹配第一个和最后一个括号,但这不起作用,因为我们不想匹配空的括号,{{1} }。它也不平衡,因此它错误地匹配[]的开放方括号和key1的右方括号。

应该匹配key16的开始和结束括号(即平衡)。由于我们不想匹配空key1,我们必须保持平衡,否则我们将匹配错误的开始和结束括号。

我尝试解决的实际问题是删除[] [(如果不为空)。这个正则表达式将在代码中以递归方式运行,以便它不断删除括号,直到它找不到更多匹配项。我确实想在RegEx中递归地应用它,但无法解决它。

生成的文本应如下所示:

]

你可以在这里查看和玩我的正则表达式: https://regex101.com/r/bE0jM5/5

提前致谢

1 个答案:

答案 0 :(得分:2)

这个小怪物

/\[((\[\s*\]|[^\[\]])+)\]/

似乎可以解决问题:



text = document.querySelector('pre').textContent;

while(1) {
  
  var r = text.replace(/\[((\[\]|[^\[\]])+)\]/g, "$1");
  if(r === text) break;
  text = r;
}

document.querySelector('pre').textContent = text;

<pre>
{
    "key1": [
        {
            "key2": "",
            "key3": "",
            "key4": "",
            "key5": []
        }
    ],
    "key6": [
        {
            "key7": "",
            "key8": "",
            "key9": [
                {
                    "key10": "",
                    "key11": "",
                    "key12": "",
                    "key13": []
                }
            ],
            "key14": ""
        }
    ],
    "key15": [],
    "key16": []
}
</pre>
&#13;
&#13;
&#13;

如果您输入的实际上是JSON,那么解析它并作为对象进行操作会更好,而不是不可读且易碎的正则表达式:

&#13;
&#13;
text = document.querySelector('pre').textContent;

removeArrays = function(obj) {
  
  if(Array.isArray(obj) && obj.length === 1)
    return removeArrays(obj[0]);
  
  if(typeof obj === "object")
    for(var k in obj)
      obj[k] = removeArrays(obj[k]);
  
  return obj;
}

s = removeArrays(JSON.parse(text));

document.querySelector('pre').textContent = JSON.stringify(s,0,3);
&#13;
<pre>
{
    "key1": [
        {
            "key2": "",
            "key3": "",
            "key4": "",
            "key5": []
        }
    ],
    "key6": [
        {
            "key7": "",
            "key8": "",
            "key9": [
                {
                    "key10": "",
                    "key11": "",
                    "key12": "",
                    "key13": []
                }
            ],
            "key14": ""
        }
    ],
    "key15": [],
    "key16": []
}
</pre>
&#13;
&#13;
&#13;