这是我到目前为止创建的正则表达式:
\((.+?)\)
这是我的测试字符串:(2+2) + (2+3*(2+3))
我得到的比赛是:
(2+2)
和
(2+3*(2+3)
我希望我的比赛是:
(2+2)
和
(2+3*(2+3))
我应该如何修改我的正则表达式?
这是我到目前为止创建的正则表达式:
\((.+?)\)
这是我的测试字符串:(2+2) + (2+3*(2+3))
我得到的比赛是:
(2+2)
和
(2+3*(2+3)
我希望我的比赛是:
(2+2)
和
(2+3*(2+3))
我应该如何修改我的正则表达式?
您不能使用正则表达式解析父级表达式。有一个数学证明正则表达式不能做到这一点。带括号的表达式是一种上下文无关的语法,因此可以被下推自动机(堆栈机器)识别。
无论如何,您可以定义一个正则表达式,该表达式将适用于任何小于 N 括号的表达式,具有任意有限 N(即使表达式会变得复杂)。你只需要承认你的括号可能包含另一个任意数量的 parenteses。
\(([^()]+(\([^)]+\)[^)]*)*)\)
它是这样工作的:
\(([^()]+
匹配一个左括号,后跟不是括号的;(\([^)]+\)[^)]*)*
可选地,可能有另一个组,由一个左括号组成,其中包含一些内容,然后是一个匹配的右括号。后面可能会出现一些其他非括号字符。这可以重复任意次数。无论如何,最后,必须有)\)
另一个右括号,与第一个匹配。这应该适用于嵌套深度 2。如果您想要嵌套深度 3,则必须进一步递归,允许我在第 (2) 点描述的每个组都有一个嵌套的括号组。
如果您使用堆栈,事情会变得容易得多。如:
foundMatches = [];
mStack = [];
start = RegExp("\\(");
mid = RegExp("[^()]*[()]?");
idx = 0;
while ((idx = input.search(start.substr(idx))) != -1) {
mStack.push(idx);
//Start a search
nidx = input.substr(idx + 1).search(mid);
while (nidx != -1 && idx + nidx < input.length) {
idx += nidx;
match = input.substr(idx).match(mid);
match = match[0].substr(-1);
if (match == "(") {
mStack.push(idx);
} else if (mStack.length == 1) {
break;
}
nidx = input.substr(idx + 1).search(mid);
}
//Check the result
if (nidx != -1 && idx + nidx < input.length) {
//idx+nidx is the index of the last ")"
idx += nidx;
//The stack contains the index of the first "("
startIdx = mStack.pop();
foundMatches.push(input.substr(startIdx, idx + 1 - startIdx));
}
idx += 1;
}
您如何在没有正则表达式的帮助下使用循环自己解析它?这是一种简单的方法:
最后,您需要在完成读取匹配时将缓冲区的内容转储到某个地方。
当您逐个字符地读取字符串时,遇到“(”时将增加 1 级,遇到“)”时会减少 1 级。然后,您会将字符放入缓冲区。
此方法假定只要您有一个“(”,输入字符串中总会有一个相应的“)”。此方法将处理任意数量的括号。