2012-01-26 110 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