2016-10-04 126 views
4

基本上,我需要組合\k\g匹配與前一組匹配的字符數量相同

下面是一個例子:

我具有在"123045 ; 67089"形式的字符串。只有在數字結尾的同一位置上兩個數字都有重複數字時,我才必須匹配。在這種情況下,123045中的0與數字的末尾相距兩個位置,67089中的0也是如此。


的問題是,如果我使用反向引用,數字的整個剩餘部分必須匹配(又名4589):

^\d*(\d)(\d*) ; \d*\1\2$ 

如果我使用模式的重新執行,我不得不放棄剩餘字符的特定數目(在這種情況下 - 2):

^\d*(\d)(\d{2}) ; \d*\1\g<2>$ 

是的,它必須在一個單一的正則表達式中。

+0

只是一個非常快速的出手,不知道是否Ruby支持PCRE完全,不充分的測試:https://regex101.com/r/u0ZBdR/3 –

+1

@SebastianProske:紅寶石正則表達式在Onigmo上運行,而不是PCRE。它通過'\ g '符號來支持遞歸。使用[Rubular](http://rubular.com)來測試Ruby正則表達式模式。 –

+0

@SebastianProske,這很聰明,我應該想到類似的東西。即使它不處理無效輸入,但可以調整。發佈這個答案(只需用'\ g <2>'替換'(?2)')。 – ndn

回答

3

你在這裏面臨的是一個平衡的問題。您可以使用遞歸來解決它,我的做法是:

^\d*(\d)(?:(\d(?:(\s*;\s*\d*\1)|\g<2>)\d)|\g<3>)$ 

這將需要\s*;\s*\d*\1爲數字的兩個平衡組之間的內容。爲了避免遞歸,這個內容必須只匹配一次(以避免像12212;1;13這樣的匹配)。作爲交替的這種內容的遞歸是對於每一個數字的最後一位數字加倍的情況。

你可以找到一些測試用例here