我试图使用正则表达式检查一个数字是否有效,但我收到错误并且不确定如何写这个。
regex e{R"(((^666)|(^900-999))(-*)([^0-6])(-*)(\d{4}))"};
所以我想说的是"检查:一个不是666或900-999的数字,然后是一个可选的连字符,一个0-6的数字和一个可选的连字符,然后是4位数。
我试过运行它,但不管我放什么,控制台告诉我输入总是不正确。
任何帮助都将不胜感激。
答案 0 :(得分:5)
这不是正则表达式非常适合的任务。
如果要检查的数字不等于666或在900-999范围内,您需要将其分解为以下丑陋的案例:
作为一个正则表达式,它是(为了清晰起见添加了一些空格):
(
[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}
- 一个四位数字。