正则表达式不包括666和900-999

时间:2015-12-09 02:24:47

标签: c++ regex

我试图使用正则表达式检查一个数字是否有效,但我收到错误并且不确定如何写这个。

regex e{R"(((^666)|(^900-999))(-*)([^0-6])(-*)(\d{4}))"};

所以我想说的是"检查:一个不是666或900-999的数字,然后是一个可选的连字符,一个0-6的数字和一个可选的连字符,然后是4位数。

我试过运行它,但不管我放什么,控制台告诉我输入总是不正确。

任何帮助都将不胜感激。

2 个答案:

答案 0 :(得分:5)

这不是正则表达式非常适合的任务。

如果要检查的数字不等于666或在900-999范围内,您需要将其分解为以下丑陋的案例:

  • 不是6或9的数字,后跟两个以上的数字
  • 6后跟一个不是6的数字,然后是一个数字
  • 66后跟另外一个不是6的数字

作为一个正则表达式,它是(为了清晰起见添加了一些空格):

(
    [0-578][0-9][0-9]
    |
    6[0-57-9][0-9]
    |
    66[0-57-9]
)

正如您所看到的,这不是一个合理的方法。保留正则表达式以检查格式,然后在代码中单独检查逻辑问题(如“不能是666或900-999”)。作为奖励,这将允许您为这些逻辑问题提供精确的错误消息,而不是将它们归结为通用的“错误格式”错误。

答案 1 :(得分:1)

如果您决定仅使用正则表达式执行此操作,那么您想要的是否定前瞻。但是,这不是某些正则表达式规范的一部分。在C ++中,唯一兼容的语法选项是std::regex_constants::ECMAScript,这在构造std::regex时恰好是默认选项。

否定前瞻由(?!<expr>)表示,如果<expr>在该点匹配,则不会匹配。例如,(?!666)将禁止使用文字字符串&#34; 666&#34;从匹配中的那一点出现。

我们可以用它来修复你原来的正则表达式。请注意,我也为此添加了一些非详尽的tests

std::regex e{R"((?!666|9\d{2})\d+-?[0-6]-?\d{4})"};

让我们分解一下:

(?!666|9\d{2}) - 我们有一个负面的预测,当666或者以9开头的三位数字出现在开头时,它会阻止这种情况的匹配。

\d+ - 这是我们匹配的数字,不能是666或900s。我选择匹配任意数量的数字,因为问题没有另外说明。

?- - 一个可选的连字符。您的问题包含-*,这是零个或多个连字符。

[0-6] - 从0到6的单个数字。您的问题有一个主要的插入符号,它具有否定字符集的效果。除了0-6之外,这将允许任何字符。

-? - 另一个可选的连字符。

\d{4} - 一个四位数字。