我的代码通过一个文件来查找日期,但是它没有返回,因为它找到了与我的正则表达式的匹配。
CODE:
std::string s(line);
std::smatch m;
std::regex e("^[0,1]?\d{1}\/(([0-2]?\d{1})|([3][0,1]{1}))\/(([1]{1}[9]{1}[9]{1}\d{1})|([2-9]{1}\d{3}))$");
std::cout << "Target sequence: " << s << std::endl;
std::cout << "Regular expression: ^[0,1]?\d{1}\/(([0-2]?\d{1})|([3][0,1]{1}))\/(([1]{1}[9]{1}[9]{1}\d{1})|([2-9]{1}\d{3}))$" << std::endl;
std::cout << "The following matches and submatches were found:" << std::endl;
while (std::regex_search(s, m, e)) {
for (auto x : m) std::cout << x << " ";
std::cout << std::endl;
s = m.suffix().str();
}
输出:
Success
Target sequence: 12/28/2002 2 15 38 43 50
Regular expression: ^[0,1]?d{1}/(([0-2]?d{1})|([3][0,1]{1}))/(([1]{1}[9]{1}[9]{1
}d{1})|([2-9]{1}d{3}))$
The following matches and submatches were found:
Enter q to quit:
我的正则表达式不正确还是别的?
答案 0 :(得分:3)
原因在于你的正则表达式以及如何指定字符串文字:
在我们对您的正则表达式进行任何修复之前,请尝试将字符串文字打印到控制台:
std::cout << "^[0,1]?\d{1}\/(([0-2]?\d{1})|([3][0,1]{1}))\/(([1]{1}[9]{1}[9]{1}\d{1})|([2-9]{1}\d{3}))$";
您会看到\
缺失,<regex>
无法看到它们。
要在字符串中指定\
,您需要将其转义\\
。
顺便说一下,打印字符串是语言中的调试步骤之一,其中没有专用的RegExp文字,并且必须通过字符串完成构造。
您正在使用^
和$
来锚定搜索。如果日期在一行中独立,它只会找到一个匹配,并且甚至不能有前导或尾随空格。
您有很多冗余语法,例如[1]{1}
或。可以取出具有单个字符的字符类(在正则表达式中不是特殊字符),即1{1}
。 {1}
始终多余,即[1]{1}
可缩短为1
。
/
不需要在字符串文字或正则表达式中进行转义。
修复上述语法问题并移除^
和$
:
"[0,1]?\\d/(([0-2]?\\d)|(3[0,1]))/((199\\d)|([2-9]\\d{3}))"
按[0,1]
,您可能需要[01]
。如果您想匹配字符A
或B
,只需将它们放在字符类[AB]
中。您的[0,1]
也会与逗号,
匹配。
您可以将()
放入([0-2]?\\d)
,(3[0,1])
。年份相同。外部捕获组就足够了。
应用以上2点:
"[01]?\\d/([0-2]?\\d|3[01])/(199\\d|[2-9]\\d{3})"
当您想要提取数据时,正则表达式现在应该可以正常工作,但如果要使用它来验证则不太好。我不知道为什么你把这一年限制在1990年到9999年,但这可能是你的商业逻辑。