Regex不包括666和900-999

Regex do not include 666 and 900-999

本文关键字:900-999 不包括 Regex      更新时间:2023-10-16

我试图使用regex来检查一个数字是否有效,但我遇到了一个错误,不知道如何编写。

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

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

我试着运行这个,但无论我放什么,控制台告诉我的输入总是不正确的。

如有任何帮助,我们将不胜感激。

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

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

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

负前瞻由(?!<expr>)表示,其中如果<expr>在该点匹配,则将不存在匹配。例如,(?!666)将禁止文字字符串"666"出现在匹配中的该点。

我们可以使用它来修复您的原始正则表达式。请注意,我也为此进行了一些非详尽的测试。

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

让我们分解一下:

(?!666|9d{2})-当666或以9开头的三位数字出现在开头时,我们有一个负面的前瞻性,阻止了匹配。

d+-这是我们匹配的数字,不能是666或在900年代。我选择在这里匹配任何数字,因为问题没有指定其他数字。

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

[0-6]-从0到6的一位数字。您的问题有一个前导插入符号,其效果是否定字符集。这将允许0-6以外的任何字符。

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

d{4}-四位数字。