【问题标题】:Regex do not include 666 and 900-999正则表达式不包括 666 和 900-999
【发布时间】:2015-12-09 02:24:47
【问题描述】:

我正在尝试使用正则表达式来检查一个数字是否有效,但我收到一个错误并且不知道如何编写。

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

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

我尝试运行它,但无论我输入什么,控制台都会告诉我我的输入总是不正确的。

任何帮助将不胜感激。

【问题讨论】:

  • "900-999" 表示数量范围,正则表达式对字符模式起作用。一般来说,您应该考虑分解您的模式以查看哪些部分有效,哪些无效。 “(^666)”是指“不是 666 的数字”吗?可能不是,它可能是指“一个不是6 的字符后跟两个6 字符。
  • @BrianCain 不,^666 指的是出现在字符串开头的字符串“666”。 ^ 仅反转字符集(例如,[^a-z])。
  • @duskwuff - 好的,好点。所以我会回去分解模式。让我们看看我们是否可以匹配“一个不是'666'的数字”:这个数字必须完全是三个数字吗? ...最多三位数?
  • 如果连字符前的数字小于 100 会怎样?这是允许的吗? 001-0-1234 应该是有效输入吗? 1-0-1234 呢?或者(不带连字符)101234?
  • -* 匹配一个可选的sequence 破折号,而不仅仅是一个可选的破折号。你可能想要-?

标签: c++ regex


【解决方案1】:

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

如果您想检查一个不等于 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”)。作为奖励,这将允许您针对这些逻辑问题提供准确的错误消息,而不是将它们归为一般的“错误格式”错误。

【讨论】:

  • 所以在 [0-578] 块中不是说零到五百七十八,而是零、五、七和八?
  • 如果正则表达式支持它,负前瞻仍然会工作。例如,所有不在 900 或 666 中的三位数字:(?!666)(?!9\d{2})\d{3}
  • @AAA 正确。字符组(方括号中的任何内容)匹配单个字符;括号中的内容定义了匹配的字符。
  • @chris 这是一个很好的观点。介意把它写成另一个答案吗?清楚的是它只适用于 PCRE 或兼容。
【解决方案2】:

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

负前瞻由(?!<expr>) 表示,如果<expr> 在该点匹配,则将不匹配。例如,(?!666) 将不允许字符串“666”出现在匹配的那个点上。

我们可以使用它来修复您原来的正则表达式。请注意,我也为此添加了一些非详尽的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} - 四位数字。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-07-01
    • 1970-01-01
    • 2013-06-15
    • 2011-04-20
    • 2014-06-19
    • 1970-01-01
    相关资源
    最近更新 更多