c++ - 奇怪的正则表达式机器与测试仪不同

标签 c++ regex

我遵循正则表达式来匹配输入字符串上的 HTTP header 和正文:

([^()<>@,;:\\\"/\\[\\]?={}\\s\\t]+):(?:[\\s\\t]+)?(.+)\\r\\n(?:\\r\\n([\\s\\S]+))?

下面的括号显示预期的匹配:

(Header-Name): (Its_value)
(Im-a-header): (Im_a_value)

(Anything here,
commonly HTML code...
...)

它在 Regex101.com 中使用 PCRE、Python 或 JavaScript 风格运行良好,但当我在 C++ 中使用 regex_search 对其进行测试时,只有第一个标题匹配,没有更多,甚至 body 。使用来自 boost::regex 的 Perl 风格产生更奇怪的输出。

测试代码:

#include <regex>
#include <string>
#include <iostream>

int main()
{
        const std::string data("Name: value\r\nFoo: bar\r\n\r\nanything\r\nhere");
        std::regex pattern("([^()<>@,;:\\\"/\\[\\]?={}\\s\\t]+):(?:[\\s\\t]+)?(.+)\\r\\n(?:\\r\\n([\\s\\S]+))?");
        std::smatch result;

        std::regex_search(data, result, pattern);

        for(const auto &match : result)
                std::cout << match << std::endl;
}

输出:

Name: value

Name
value

输出从 std 改变至 boost (并自动转换为 Perl 风格):

Name: value
Foo: bar

anything here

Name
value
Foo: bar

anything here

观察:我使用了 boost仅用于测试结果输出。我不想要任何特定于 Perl 的解决方案。

我想用这样的代码得到类似于下面的输出:

Name
value
Foo
bar
anything
here

有人可以了解问题所在并帮助我解决这个问题吗?

最佳答案

似乎有几个问题。

  1. 您需要多次运行 regex_search 以获得多个匹配项,每个匹配项都有捕获组。
  2. 由于您需要修改输入字符串,因此需要将其声明为非常量。
  3. 正则表达式本身将 anything\r\nhere 放入第 3 组,您应该在尝试打印/获取它之前检查它是否已填写。

这是一个固定版本:

string data("Name: value\r\nFoo: bar\r\n\r\nanything\r\nhere");
std::regex pattern("([^()<>@,;:\\\\\"/\\[\\]?={}\\s]+):\\s*(.+)\r\n(?:\r\n([\\s\\S]+))?");
std::smatch result;

while (regex_search(data, result, pattern)) {
    std::cout << result[1] << "\n" << result[2] << std::endl;
    if (result[3].str().size() > 0)
    {
        std::cout << result[3] << std::endl;
    }
    data = result.suffix().str();
}

参见 IDEONE demo .输出:

Name
value
Foo
bar
anything
here

关于c++ - 奇怪的正则表达式机器与测试仪不同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32450249/

相关文章:

c++ - 错误 C1190 : managed targeted code requires a '/clr' option

c++ - GCC:我什么时候可以期望返回大型 C++ 对象是高效的?

java - Java 正则表达式问题\b

javascript - 如何将带括号的字符串解析为数组数组?

c++ - 当 Qt 信号/槽连接失败时,如何提醒我?

c++ - kernel.cpp 在制作 kernel.o 时显示错误和 Makefile 错误

c++ - 如何处理 libstdc++ 跨执行边界抛出异常

Java:使用正则表达式从 block 注释中去除斜杠和星号

regex - 如何在 Perl 正则表达式中替换第 n 次匹配?

c# - 如何通过正则表达式设置第一个字符?