查找与给定字符串中的两个 children 子字符串匹配的正则表达式

Finding regex that matches two children substrings within given string

我正在尝试创建一个正则表达式,它将显示给定字符串中的两个子字符串,并且返回值应该是一个包含两个元素的数组,即两个匹配的字符串。我知道我的问题与不能作为正则表达式实现的回文密切相关,但我希望正则表达式能够足够接近,因为我期望读取的是有限大小的结构。

说的很具体,我只关心匹配第一个例子中的两个top-level children,里面嵌套多少个括号都无所谓,有没有1个或其中的 99999 个。

请注意,空格只是为了便于阅读,输入的字符串将没有空格。这个结构很简单:

{ }{ }

并且应该被接受为两个字符串:

{ } and { }

其中包含任意数量的大括号分组:

{ {} {} {} {} {} {} }{ {} }

并且应该被接受为两个字符串:

{ {} {} {} {} {} {} } and { {} }

包含在这些大括号内部分组中的任何一个都可以是无限递归分组,例如:

{{{{ }{{ }}{ }}}}{{ }{ }{ }}

并且应该被接受为两个字符串:

{{{{ }{{ }}{ }}}} and {{ }{ }{ }}

这个问题我自己想了很久,一直想不出一个合适的解决方案,而且我发现网上没有任何工具可以直观地查看这两个子字符串, 它总是只匹配整个字符串。我还使用了一些正则表达式创建器,如“http://regex.inginf.units.it/”,并为其提供了最大数量的字符串和所有可能的边缘情况等,但只有 40% 的准确率。我希望在这个问题上比我更聪明的人可以想出一个正则表达式来拟合最后 7 个示例的答案以及根据上述规则构造的任何其他可能的字符串。

我做了一个简单的 html 来测试我的字符串(只需编辑脚本标签中的 "reg" 变量来更改您的正则表达式并使用刷新页面查看结果:

var reg = /({({.*})*})/g;
var str1 = "{}{}";
var str2 = "{{}{}}{{}}";
var str3 = "{{{{{}{}{}{}}{{}}}}{}}{}";
var str4 = "{{{{{{{{{{{{{{{{{}}{{}}}}}{{}}}}}{{}}}}}{{}}}}}{{}}}}}{{}}";
var str5 = "{{}{{{{{{}{}}}}{{{{}{}}}{}}}}{}{{{}{{}}}}}{{{{{}}{{{{}{}}}}}}{{{{}}{{{{}{}}}}}}}";
var str6 = "{{}{}}{{}{{{}{}}}}";
var str7 = "{{}{}}{{{{{}}{{}}}}{{{}{}}}}";
var s1 = document.getElementById("d1").innerHTML = str1.match(reg);
var s2 = document.getElementById("d2").innerHTML = str2.match(reg);
var s3 = document.getElementById("d3").innerHTML = str3.match(reg);
var s4 = document.getElementById("d4").innerHTML = str4.match(reg);
var s5 = document.getElementById("d5").innerHTML = str5.match(reg);
var s6 = document.getElementById("d6").innerHTML = str6.match(reg);
var s7 = document.getElementById("d7").innerHTML = str7.match(reg);
<p id="d1"></p>
<p id="ans1">{},{}</p>
<p id="d2"></p>
<p id="ans2">{{}{}},{{}}</p>
<p id="d3"></p>
<p id="ans3">{{{{{}{}{}{}}{{}}}}{}},{}</p>
<p id="d4"></p>
<p id="ans4">{{{{{{{{{{{{{{{{{}}{{}}}}}{{}}}}}{{}}}}}{{}}}}}{{}}}}},{{}}</p>
<p id="d5"></p>
<p id="ans5">{{}{{{{{{}{}}}}{{{{}{}}}{}}}}{}{{{}{{}}}}},{{{{{}}{{{{}{}}}}}}{{{{}}{{{{}{}}}}}}}</p>
<p id="d6"></p>
<p id="ans6">{{}{}},{{}{{{}{}}}}</p>
<p id="d7"></p>
<p id="ans7">{{}{}},{{{{{}}{{}}}}{{{}{}}}}</p>

正则表达式不适合这个任务(至少 JS 风格不适合)。任何涉及可以任意嵌套结构的东西都不适合用regex匹配。这就是为什么他们说 you should not use regex to parse HTML or JSON. See this answer 以获取更多信息。

无需使用正则表达式即可轻松解析此处的字符串。通过使用正则表达式,你有点让自己的生活变得艰难。

解析此字符串的方法如下(假设括号始终平衡):

  • 遍历字符串
  • 如果遇到左大括号,将其加一到计数器变量
  • 如果遇到右大括号,减去一个
  • 计数器变量第一次为0,即第一个子串结束,其余为第二个子串。