2013-08-22 255 views
0

這是我創建至今的正則表達式: \((.+?)\) 正則表達式的括號(JavaScript的)

這是我的測試字符串:(2+2) + (2+3*(2+3))

的比賽我得到的是:

(2+2)(2+3*(2+3)

我想要我的比賽是:

(2+2)(2+3*(2+3))

我應該如何修改我的正則表達式?

+5

對於像這樣的遞歸結構解析正則表達式不是一個好的選擇。 –

+0

這是蟒蛇,但它會指向你在一個可行的(非正則)方法的方向: http://stackoverflow.com/questions/524548/regular-expression-to-detect-semi-colon-terminated -c-for-while-loops/524624#524624 – jwrush

回答

4

您不能使用正則表達式解析帶有parentesized的表達式。 有一個數學證明,正則表達式不能做到這一點。 括號的表達式是上下文無關文法,和因此可以由下推自動機識別(堆疊機)。

可以,反正定義的正則表達式可以在任何表達工作,小於N括號,用任意有限N(即使表達將變得複雜)。 你只需要確認你的圓括號可能包含另一個任意數量的伴奏。

\(([^()]+(\([^)]+\)[^)]*)*)\)

它的工作原理是這樣的:

  1. \(([^()]+一個開放的括號,以任何不是括號follwed匹配;
  2. (\([^)]+\)[^)]*)*可選地,可能存在另一個組,由左括號與其中的內容組成,然後是一個匹配的右括號。其他一些非括號字符可能會出現。這可以重複任意次數。無論如何,最後,必須有另一個封閉的括號,它與第一個匹配。

這應爲嵌套深度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; 
} 
+0

當然,如果你不打算用超過2-3個嵌套括號解析表達式,堆棧機是不值得的 –

1

你如何解析它自己使用循環沒有正則表達式的幫助? 這裏有一個簡單的方法:

  • 你就必須有一個變量,說「級別」,以跟蹤你有多少開括號遇到至今(以0初始化)。
  • 您還需要一個字符串緩衝區來包含每個匹配項(例如(2 + 2)或(2 + 3 *(2 + 3)))。
  • 最後,您需要某處可以將緩衝區的內容轉儲到每當完成閱讀比賽時。

  • 當你逐字符地讀取字符串時,當遇到「(」,當遇到「」時遞減1)時,你會遞增1。然後你會將該字符放入緩衝區。

  • 當你遇到「)」並且水平恰好爲0時,那就是當你知道你有一個匹配時。這是當你轉儲緩衝區的內容並繼續。

該方法假定只要你有一個「(」將始終有一個相應的「)」在輸入字符串。該方法將處理任意數量的括號。