我希望匹配以下模式
(1)
10digits sometext (例如1235873490 ABCD EFGK)
在可能具有上述模式的文本中,以及与此类似的非常相似的模式
(2)
10digits 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。
答案 0 :(得分: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+)
或者,如果您知道 sometext 中总会有2个部分,这也将解决回溯问题:
(\d{10}(?:\s+\w+){2} # can only occur twice
)
(?=\s|$)(?!\s*\d+\.\d+)