正则表达式,找不到匹配

时间:2014-10-17 02:04:34

标签: c++ regex fstream

我的代码通过一个文件来查找日期,但是它没有返回,因为它找到了与我的正则表达式的匹配。

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:

我的正则表达式不正确还是别的?

1 个答案:

答案 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]。如果您想匹配字符AB,只需将它们放在字符类[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年,但这可能是你的商业逻辑。