這是我創建至今的正則表達式: \((.+?)\)
正則表達式的括號(JavaScript的)
這是我的測試字符串:(2+2) + (2+3*(2+3))
的比賽我得到的是:
(2+2)
而 (2+3*(2+3)
我想要我的比賽是:
(2+2)
而 (2+3*(2+3))
我應該如何修改我的正則表達式?
這是我創建至今的正則表達式: \((.+?)\)
正則表達式的括號(JavaScript的)
這是我的測試字符串:(2+2) + (2+3*(2+3))
的比賽我得到的是:
(2+2)
而 (2+3*(2+3)
我想要我的比賽是:
(2+2)
而 (2+3*(2+3))
我應該如何修改我的正則表達式?
您不能使用正則表達式解析帶有parentesized的表達式。 有一個數學證明,正則表達式不能做到這一點。 括號的表達式是上下文無關文法,和因此可以由下推自動機識別(堆疊機)。
可以,反正定義的正則表達式可以在任何表達工作,小於N括號,用任意有限N(即使表達將變得複雜)。 你只需要確認你的圓括號可能包含另一個任意數量的伴奏。
\(([^()]+(\([^)]+\)[^)]*)*)\)
它的工作原理是這樣的:
\(([^()]+
一個開放的括號,以任何不是括號follwed匹配;(\([^)]+\)[^)]*)*
可選地,可能存在另一個組,由左括號與其中的內容組成,然後是一個匹配的右括號。其他一些非括號字符可能會出現。這可以重複任意次數。無論如何,最後,必須有另一個封閉的括號,它與第一個匹配。這應爲嵌套深度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;
}
當然,如果你不打算用超過2-3個嵌套括號解析表達式,堆棧機是不值得的 –
你如何解析它自己使用循環沒有正則表達式的幫助? 這裏有一個簡單的方法:
最後,您需要某處可以將緩衝區的內容轉儲到每當完成閱讀比賽時。
當你逐字符地讀取字符串時,當遇到「(」,當遇到「」時遞減1)時,你會遞增1。然後你會將該字符放入緩衝區。
該方法假定只要你有一個「(」將始終有一個相應的「)」在輸入字符串。該方法將處理任意數量的括號。
對於像這樣的遞歸結構解析正則表達式不是一個好的選擇。 –
這是蟒蛇,但它會指向你在一個可行的(非正則)方法的方向: http://stackoverflow.com/questions/524548/regular-expression-to-detect-semi-colon-terminated -c-for-while-loops/524624#524624 – jwrush