30

我正在尝试使用正则表达式来尝试回答这个问题,并发现虽然regex_match找到了匹配项,regex_search但没有。

以下程序使用 g++ 4.7.1 编译:

#include <regex>
#include <iostream>

int main()
{
    const std::string s = "/home/toto/FILE_mysymbol_EVENT.DAT";
    std::regex rgx(".*FILE_(.+)_EVENT\\.DAT.*");
    std::smatch match;

    if (std::regex_match(s.begin(), s.end(), rgx))
        std::cout << "regex_match: match\n";
    else
        std::cout << "regex_match: no match\n";

    if (std::regex_search(s.begin(), s.end(), match, rgx))
        std::cout << "regex_search: match\n";
    else
        std::cout << "regex_search: no match\n";
}

输出:

正则表达式匹配:匹配
regex_search: 不匹配

我的假设是两者都应该匹配错误,还是 GCC 4.7.1 中的库可能存在问题?

4

4 回答 4

7

您的正则表达式在 VS 2012rc 中工作正常(两者都匹配,这是正确的)。

在 g++ 4.7.1(-std=gnu++11)中,如果使用:

  • ".*FILE_(.+)_EVENT\\.DAT.*",regex_match匹配,但regex_search不匹配。
  • ".*?FILE_(.+?)_EVENT\\.DAT.*",regex_match也不regex_search匹配 (O_o)。

所有变体都应该匹配,但有些不匹配(由于betabandido已经指出的原因)。在 g++ 4.6.3(-std=gnu++0x)中,行为与 g++ 4.7.1 相同。

Boost (1.50)可以正确匹配所有模式类型。

摘要

                        正则表达式匹配正则表达式搜索
 -------------------------------------------------- ---
 g++ 4.6.3 linux OK/- -
 g++ 4.7.1 linux OK/- -
 与 2010 年相比 好的 好的
 vs 2012rc OK OK
 提升 1.50 胜利 OK OK
 boost 1.50 linux OK OK
 -------------------------------------------------- ---

关于你的模式,如果你的意思是一个点字符'.',那么你应该这样写("\\.")。您还可以通过使用非贪婪修饰符 ( ?) 来减少回溯:

".*?FILE_(.+?)_EVENT\\.DAT.*"
于 2012-07-24T10:58:53.517 回答
7

假设 C++ 和Boost Regex具有相似的结构和功能,这里解释了regex_match和之间的区别:regex_search

regex_match()如果正则表达式从头到尾匹配整个输入,该算法只会报告成功。如果正则表达式只匹配输入的一部分,regex_match()将返回 false。如果要在字符串中搜索正则表达式匹配的子字符串,请使用regex_search()算法。

于 2015-05-08T10:22:24.880 回答
4

查看最新的 libstdc++源代码regex_search您会发现:

* @todo Implement this function.

不幸的是,这不是剩下的唯一 TODO 项。GCC 的<regex>实现目前还不完整。#ifdef我建议在 GCC 赶上之前使用 Boost 或 Clang 和代码。

(这在 4.8 分支中都没有修复。)

于 2012-07-24T16:16:31.243 回答
2

我尝试在 C++11 中使用正则表达式库,但遇到了很多问题(都使用 g++ 4.6 和 4.7)。基本上,要么没有支持,要么只有部分支持。即使是 SVN 版本也是如此。在这里,您有一个链接,描述了libstdc++ 的 SVN 版本的当前状态

所以,就目前而言,我想最好的选择是继续使用Boost.Regex

或者,您可以尝试使用libc++。根据这个文档,对正则表达式的支持是完整的。

于 2012-07-24T10:03:54.603 回答