C++ 正则表达式不包括666和900-999
我试图使用正则表达式来检查一个数字是否有效,但我得到了一个错误,不知道如何写这个C++ 正则表达式不包括666和900-999,c++,regex,C++,Regex,我试图使用正则表达式来检查一个数字是否有效,但我得到了一个错误,不知道如何写这个 regex e{R"(((^666)|(^900-999))(-*)([^0-6])(-*)(\d{4}))"}; 所以我想说的是“检查:一个不是666或900-999的数字,然后是可选的连字符,一个0-6和可选的连字符,然后是4位数字 我试着运行这个,但是不管我放什么,控制台都告诉我我的输入总是不正确的 任何帮助都将不胜感激。这不是正则表达式非常适合的任务 如果要检查不等于666或不在900-999范围内的数字
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的数字
正如您所看到的,这不是一种合理的方法。保留正则表达式以检查格式,然后在代码中单独检查逻辑问题(如“不能是666或900-999”)。作为奖励,这将允许您为这些逻辑问题提供精确的错误消息,而不是将它们归为一般的“错误格式”“错误。如果您决定只使用正则表达式执行此操作,那么您需要的是一个消极的前瞻。”。但是,这不是某些正则表达式规范的一部分。在C++中,唯一兼容的语法选项是:代码> STD::ReExxIOrth::EcMAScript < /COD>,这在构建<代码> STD::ReXEX < /C> >:时是默认的。 负前瞻由
(?!)
表示,如果
在该点匹配,则不存在匹配。例如,(?!666)
将禁止文本字符串“666”出现在匹配中的该点
我们可以使用它来修复原始正则表达式。请注意,我也为此输入了一些非详尽的信息
std::regex e{R"((?!666|9\d{2})\d+-?[0-6]-?\d{4})"};
让我们分解一下:
(?!666 | 9\d{2})
-当666或以9开头的三位数字出现在开头时,我们有一个负的前瞻性,阻止匹配
\d+
-这是我们正在匹配的号码,不能是666或900。我选择在这里匹配任意数量的数字,因为问题没有另外指定
?-
-可选连字符。您的问题包含-*
,它是零个或多个连字符
[0-6]
-0到6之间的一个数字。您的问题有一个前导插入符号,它具有否定字符集的效果。这将允许除0-6之外的任何字符
-?
-另一个可选连字符
\d{4}
-一个四位数字。“900-999”表示数量范围和字符模式的正则表达式。一般来说,你应该考虑分解你的模式,看看哪些部分有效,哪些不起作用。“(^666)
”是否指“不是666的数字”?可能不是,它可能是指“一个不是6
的字符,后跟两个6
字符。@BrianCain No,^666
是指出现在字符串开头的字符串“666”。^
仅反转字符集(例如,[^a-z]
)@Daskwuff-好的,很好的观点。那么我将继续分解模式。让我们看看是否可以匹配“一个不是‘666’的数字”:数字必须精确地有三位数吗?…最多三位数?如果连字符前的数字小于100会怎么样?允许吗?001-0-1234应该是有效输入吗?1-0-1234呢?或者(不带连字符)101234?和-*
匹配可选的破折号序列,而不仅仅是可选的破折号。您可能需要-?
。因此在块[0-578]它不是说0到578,而是说0、5、7和8?如果正则表达式支持它,那么一个负的前瞻仍然有效。例如,所有不在900或666中的三位数:(?!666)(?!9\d{2})\d{3}
@AAA正确。字符组(方括号中的任何内容)匹配单个字符;括号中的内容定义了要匹配的字符。@chris这是一个很好的观点。介意将其作为另一个答案写出来吗?请清楚,它只适用于PCRE或compatible。
std::regex e{R"((?!666|9\d{2})\d+-?[0-6]-?\d{4})"};