奇怪的正则表达式匹配行为。我的正则表达式错了吗?还是编译器错误?

Weird regex match behavior. Is my regex wrong? Or is it a compiler error?

我正在使用 C++ 中的正则表达式做一些工作,尝试了 std::regex 和 boost:regex (1.58.0)。

我得到了这个奇怪的匹配项。这是代码:

#include <iostream>
#include <regex>
using namespace std;

int main(int argv, const char* argc[])
{
    regex log_line_regex_(".+\s(.+)$");
    char* log_line = "06-29 18:20:08.938 1031 1099 D WifiStateMachine: processMsgConnect oo ModeState";
    smatch matches; 
    if (regex_match(std::string(log_line), matches, log_line_regex_))
    {
        std::cout << "match: " << log_line << std::endl;
        unsigned i;
        for (i = 0; i < matches.size(); i++)
        {
            std::cout << "$" << i << ": " << std::string(matches[i].first, matches[i].second) << std::endl;
        }
    }
    return 0;
}

结果是:

match: 06-29 18:20:08.938 1031 1099 D WifiStateMachine: processMsgConnect oo ModeState
[=11=]: 06-29 18:20:08.938 1031 1099 D WifiStateMachine: processMsgConnect oo ModeSt`
: ModeSt`

看到了吗?输出被破坏:( 正如我所说,我在 Cygwin

上尝试使用 boost 1.58.0g++ (GCC) 4.9.2

Compiled at Ideone also fails

我觉得 boost::regex 在这个简单的正则表达式中失败很奇怪。那么我的用法有误吗?

这是实施质量。

有两个问题在起作用:

  • 大多数 std 库实现没有很好地、完全地或根本没有实现 std::regex。这是混淆的常见来源。 IIRC GCC 仅支持 5.x 以上。

  • 另一个问题是您输入的 (std::string(log_line)) 是临时的 (!)。 smatch 将包含 return 迭代器到一个临时文件中,临时文件的生命周期在 regex_match 调用结束时结束。

修复它至少可以让 GCC 工作 5.x:

Live On Coliru

#include <iostream>
#include <regex>

int main()
{
    std::regex log_line_regex_(".+?\s(.+)");

    char const *log_line = "06-29 18:20:08.938 1031 1099 D WifiStateMachine: processMsgConnect oo ModeState";

    std::smatch matches;

    std::string input(log_line);
    if (regex_match(input, matches, log_line_regex_))
    {
        std::cout << "match: " << log_line << std::endl;

        for (unsigned i = 0; i < matches.size(); i++) {
            std::cout << "$" << i << ": " << std::string(matches[i].first, matches[i].second) << std::endl;
        }
    }
}

打印:

match: 06-29 18:20:08.938 1031 1099 D WifiStateMachine: processMsgConnect oo ModeState
[=11=]: 06-29 18:20:08.938 1031 1099 D WifiStateMachine: processMsgConnect oo ModeState
: 18:20:08.938 1031 1099 D WifiStateMachine: processMsgConnect oo ModeState

¹ 实际上包含 完整表达式