正则表达式:疯了吗?

时间:2011-11-16 03:33:37

标签: regex vb.net regex-negation

我有一个这样的字符串:

  

请参阅文件ABC.123.1234.1234和文件CBA.321.4321

我正在运行两个不同的正则表达式搜索,以分别识别两个不同的文档标识符。第一个标识符的表达很有用:

ABC.123.1234.1234 = \b[A-Z]{3}\.\d{1,4}\.\d{1,4}\.\d{1,4}\b

现在,我遇到的问题是尝试使用以下表达式提取较小的标识符:

\b[A-Z]{3}\.\d{1,3}\.\d{1,4}\b

不幸的是,这会返回两个结果ABC.123.1234& CBA.321.4321。我要求第二个表达式返回的唯一结果是CBA.321.4321

2 个答案:

答案 0 :(得分:1)

如果您将其更改为[A-Z]{3}\.\d{1,3}\.\d{1,4}(!\.),如果有第三个点,它会使用负向前瞻来停止匹配,这样只会为您提供所需的结果。

答案 1 :(得分:1)

不确定您使用的是哪个正则表达式系统,因为它们的语法略有不同。

你想要的是一个否定的zero-width lookahead assertion,以确保你得到你的匹配,只有\.[A-Za-z]{4}后面的匹配才会被计算。

另外,数据中的数字实际上是可变宽度吗?如果不匹配,如果您匹配{4}而不是{1,4},则会更容易获得匹配。前瞻性断言不会那么容易实现。

但你仍然可以实现它们。只需制作负面预测匹配\d*\.\d{1,4}\d*是避免部分匹配的重要部分。)

修改

由于你使用的是VB.Net,这里是Regex实现中负前瞻断言的语法:

(?!subexpression)

所以你的正则表达式可能会像:

\b[A-Z]{3}\.\d{1,4}\.\d{1,4}(?!\d*\.\d{1,4}\b)

删除较长匹配并处理可变宽度数字的重要部分是:

(?!\d*\.\d{1,4}\b)