2012-01-26 108 views
0

我期待匹配以下模式前瞻正則表達式

(1)

10digits sometext(如1235873490 ABCD EFGK)

在可能有上述模式的文本,以及非常類似的模式像這樣的

(2)

10位數字sometext decimal_number(例如9835873490 VBGF XMF 23.233)

如何寫正則表達式來僅匹配模式(1)並忽略模式(2)?

我一直在使用這樣的事情看着負向前看符號:

(\d{10})\s*([A-Za-z0-9]+(?:\s+[A-Za-z0-9]+)(?:\s+[A-Za-z0-9]+))\s*(?!(\d+.\d+)) 

,但不能讓它開始工作。有任何想法嗎?順便說一句,我使用的是C++ boost :: regex。

回答

2

首先,先從簡單的版本:

(\d{10}   # 10 digits 
    (?:\s+\w+)+) # some text, separated by spaces, 
        # at least one time 
(?!\s*\d+\.\d+) # not followed by a decimal number 

我改變了你的[A-Za-z0-9]\w爲簡單起見,並允許它,因爲它要發生多次。

但是,這也會匹配第二個字符串 - 它會在末尾吞噬23,然後看到它後面沒有一個十進制數(它後面跟着「.23」),所以它會匹配。

爲了防止這種情況,我們可以說,它必須遵循的一個空間或文本的結尾:

(\d{10}(?:\s+\w+)+) 
    (?=\s|$)  # it must be followed by a space or end of text 
(?!\s*\d+\.\d+) 

然而,這仍然有問題。現在,它將匹配到「... XMF」,但接着看到後面跟着一個十進制數字,並且回溯。它會回到「... VBGF」然後匹配,因爲「VBGF」後面沒有小數。

爲了防止這種情況,我們可以告訴大家,一旦符合我們的主要部分不能走回頭路的正則表達式:

(?> # added '?>': not allowed to backtrack once this group is matched 
    \d{10}(?:\s+\w+)+)  
(?=\s|$)(?!\s*\d+\.\d+) 

或者,如果你知道總會有2份sometext ,這也將解決回溯:

(\d{10}(?:\s+\w+){2} # can only occur twice 
    )  
(?=\s|$)(?!\s*\d+\.\d+) 
+0

整潔...偉大的作品!非常感謝! – Abryan 2012-01-27 00:28:06