2012-01-26 3 views
0

Я ищу, чтобы соответствовать следующему шаблонуLookahead регулярное выражение

(1)

10digits SOMETEXT (например, 1235873490 ABCD EFGK)

В тексте, который может иметь рисунок выше, а также очень похожи картины как этот

(2)

10digits sometext decimal_number (например, 9835873490 VBGF XMF 23.233)

Как я могу написать регулярное выражение для соответствия только шаблону (1) и игнорировать шаблон (2)?

Я посмотрел на негативные lookaheads используя что-то вроде этого:

(\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

Neat ... отлично работает! Большое спасибо! – Abryan

Смежные вопросы