2017-05-22 28 views
2

我卡上的正則表達式:正則表達式和平衡組

我有一個數字的輸入字符串和一個字母,可以在字符串中和括號之間含有較多的數字和字母:

只是一個舉幾個例子

26U(35O40) will be read as 26 and (35 or 40) 
22X(34U(42O27)) will be read as 22 xor (34 and (42 or 27)) 
21O(24U27) will be read as 21 or (24 and 27) 
20X10X15 Will be read as 20 xor 10 xor 15 

我已閱讀,這可以使用均衡組中獲得,但是我已經試過很多的正則表達式和關閉的是:

(?<ConditionId>\d+)(?<Operator>X|U|O)?(?<Open>\()(?<ConditionId>\d+)+(?<Operator>X|U|O)?(?<ConditionId>\d+)(?<-Open>\)) 

我也想過,也許我讓它更難,我應該只是運行幾次相同的正則表達式,第一次爲括號外的所有內容,第二次爲內部的東西,並再次運行時匹配內。類似的東西:

(?<ConditionId>\d+)?(?<Operator>U|O|X)?(?<Inner>(?:\().*(?:\))) 

建議或幫助?

在此先感謝。

編輯1:我不必驗證輸入,只是解析它。

編輯2:因此,背後的原因是通過條件Id識別條件,然後將運算符應用於輸入字符串中的其他條件。按照與輸入字符串中出現的順序相同的順序,更易於理解的示例是邏輯門:

對於給定的輸入20x10x15,我將不得不通過conditionId來確定條件,並檢查條件是有效的,並應用XOR運算他們,是這樣的:

true X true X false = false; 
false X false X true = true; 
true X (false U true) = true 

,這是我不羣一切都變成「ConditionId」組和「操作員」組的原因。

編輯3 這也是一個有效的例子

(23X10)U(30O(20X19) 
+1

爲什麼你解決正則表達式來解決這個特定問題?您應該能夠使用常規字符串操作和堆棧來編寫解析器。 – willaien

+0

嗨,感謝您的建議,我使用了正則表達式,因爲條件實際上比我用於該示例的條件稍微複雜一些,並且我認爲正確的方法是使用正則表達式,因爲有時最難的是最簡單的,而且我不想結束與String操作的鬥爭(有時也會更困難)。 無論如何,你是對的,我一定會看看,如果我沒有得到解決與正則表達式的問題,因爲這是我的第二選擇。 – Nekeniehl

+1

你需要實際*替換*嗎?不只是*提取*部分字符串? ''22X(34U(42O27))「'=>'」22 xor(34 and(42 or 27))「' –

回答

0

如果使用(\d+[A-Z]*[()]?)+它將在22X(34U(42O27))這些捕獲回報Groups[1].Captures

22X( 34U( 42O27)

一個匹配

這提供了足夠的信息來處理代碼。

20X10X15同捕獲組給

20X10X15

0

假設你的輸入已經有效,並且要解析吧,這裏是一個相當簡單的正則表達式來實現這一目標:

(?: 
    (?<ConditionId>\d+) 
    | 
    (?<Operator>[XUO]) 
    | 
    (?<Open>\() 
    | 
    (?<Group-Open>\)) 
)+ 

Working example - Regex Storm - 切換到選項卡查看所有捕獲。

圖案捕獲:

  • 號碼到$ConditionId組。
  • 運營商劃入$Operator組。
  • 括號中的子表達式到$Group組(需要更好的名字?)。例如,對於字符串22X(34U(42O27)),它將有兩個捕獲:42O2734U(42O27)

每個capture包含匹配字符串的位置。只有使用這些位置才能表達$Group與其包含的$Operator s,$ConditionId s和$Group s之間的關係。

(?<Group-Open>)語法用於當我們到達一個右括號時捕獲自對應左括號之後的所有內容。這在這裏更詳細地解釋:What are regular expression Balancing Groups?

+0

嗨,謝謝你詳細的答案,但這是我第一次嘗試成功,問題是,所有事情後來混合 我無法組條件或運營商的原因是因爲後來我必須通過Id並以與輸入中相同的方式將運算符應用於其他條件。 – Nekeniehl