Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
JavaScript正则表达式匹配平衡结构,而不考虑不平衡结构_Javascript_Regex - Fatal编程技术网

JavaScript正则表达式匹配平衡结构,而不考虑不平衡结构

JavaScript正则表达式匹配平衡结构,而不考虑不平衡结构,javascript,regex,Javascript,Regex,我正在从事一个基于JavaScript的项目,该项目涉及一个受Bash启发的基本脚本系统,我正在使用正则表达式将行分隔为(多种类型的)标记 一个这样的令牌类当然是递归的$()构造。此构造可以任意嵌套。我试图设计一个JavaScript正则表达式来匹配这种类型的令牌,而不会意外地留下部分或抓取其他令牌的部分 更具体地说,问题在于: 给定如下示例中的字符串: “$(foo$(bar)fizz$(buzz))$(something$(other))” 它由单个标记组成,每个标记由外部$()分隔,后跟空

我正在从事一个基于JavaScript的项目,该项目涉及一个受Bash启发的基本脚本系统,我正在使用正则表达式将行分隔为(多种类型的)标记

一个这样的令牌类当然是递归的
$()
构造。此构造可以任意嵌套。我试图设计一个JavaScript正则表达式来匹配这种类型的令牌,而不会意外地留下部分或抓取其他令牌的部分

更具体地说,问题在于: 给定如下示例中的字符串:
“$(foo$(bar)fizz$(buzz))$(something$(other))”
它由单个标记组成,每个标记由外部$()分隔,后跟空格或字符串结尾, 匹配字符串中的第一个这样的标记,该标记来自并包括其打开$(到并包括其最终关闭) 如果字符串中的任何位置出现不平衡的构造,则此正则表达式的行为将被视为未定义且无关紧要。

因此,在上面的示例中,正则表达式应该匹配“$(foo$(bar)fizz$(buzz))”

更多使用详情: 输入字符串和返回的匹配项都通过
string.prototype.trim()
传递,因此前导和尾随空格并不重要

我能够将不平衡构造视为未定义的情况,因为一旦提取,使用这种类型令牌的代码将执行其自身的平衡检查。即使正则表达式返回一个由外部$()包围的匹配,错误最终也会在其他地方被捕获

到目前为止我都试过了 有一段时间我一直在使用这个正则表达式:
/\$\(.*?\)(?!(?:(?!\$\())*\)(?:\s+\$)/

这似乎在相当长的一段时间内奏效。它匹配任意嵌套的平衡结构,只要它们在同一级别上没有多个嵌套。刚开始测试时,不知怎么的,我就忘记了那个案例。它以延迟重复的方式消耗令牌的内容,并断言在结束paren之后,在有打开的$()之前,没有另一个结束paren。这当然会被上面的示例这样的令牌打破。

我知道传统的“平衡结构正则表达式问题”如果没有子程序/递归是无法解决的。但是我希望,因为我只需要匹配平衡结构,而不是不匹配不平衡结构,所以这里有一些聪明的方法来欺骗

因此,在上面的示例中,正则表达式应该匹配
$(foo$(bar)fizz$(buzz))

我看到的解决方案几乎与(基于Steven Levithan的)相同,但您只需要添加分隔符,因为它们是已知的

用法示例:

matchRecursiveRegExp("$(foo $(bar) fizz $(buzz)) $(something $(else))", "\\$\\(", "\\)");
代码:

函数匹配RecursiveEGEXP(str、左、右、标志){
var f=标志| |“”,
g=f.indexOf(“g”)>-1,
x=新的正则表达式(左+右+g+f),
l=新的RegExp(左,f.replace(/g/g,“”),
a=[],
t、 s,m;
做{
t=0;
while(m=x.exec(str)){
if(l.test(m[0])){
如果(!t++)s=x.lastIndex;
}else if(t){
if(!--t){
a、 推(str.slice(s,m.index));
如果(!g)返回a;
}
}
}
}而(t&(x.lastIndex=s));
返回a;
}

document.write($(“+matchRecursiveRegExp($(foo$(bar)fizz$(buzz))$(something$(other)),“\\$\(“,“\\)”+”)”);
您可能想先读一下,我花了一些时间才弄清楚这些变量名的逻辑(最终通过链接找到了更冗长的原始版本),但现在我明白了,这实际上相当优雅。我需要进行一些重构才能在这里使用函数,但这肯定是可行的。如果没有更巧妙的方法(可能不会),你会得到答案。