【问题标题】:Extracting data from an std::string using regex使用正则表达式从 std::string 中提取数据
【发布时间】:2020-12-13 03:59:30
【问题描述】:

类似于Parse comma-separated ints/int-ranges in C++,
我想要一个正则表达式从字符串中提取边缘:(1,2,1) (2,4,5) (1,4,3) (3,4,10) (3,6,2) (3,5,3) (6,7,6) (4,7,4) where (Node1 number, Node2 number, distance)

我目前正在使用:std::regex reg_edge("\(.*?\,.*?\,.*?\)");,它不起作用(因为找不到一个匹配项)。

由于这也可能是一个 XY 问题,我将说明我想要做什么:我希望用户在创建图形时输入图形的边缘。

请建议一个正确的正则表达式,或者可能是一个更好的方法。
我当前的代码:

void Graph::setEdges() {
    std::string edge_str;
    std::getline(std::cin, edge_str);
    std::istringstream iss(edge_str);
    edge_str.clear();
    while (iss >> edge_str) {
        std::regex reg_edge("\(.*?\,.*?\,.*?\,\)");
        auto reg_begin = std::sregex_iterator(edge_str.begin(), edge_str.end(), reg_edge);
        auto reg_end = std::sregex_iterator();
        for (std::sregex_iterator reg_it = reg_begin; reg_it != reg_end; reg_it++) {
            std::smatch it_match = *reg_it;

        }
    }
}

【问题讨论】:

  • 您可以使用简单的reg_edge(R"(\((\d+),(\d+),(\d+)\))"),然后获取组值reg_it.str(1)reg_it.str(2)reg_it.str(3)。好吧,如果您不需要详细的输出,请使用reg_edge(R"(\(\d+(?:,\d+){2}\))")
  • 对于这样一个简单的解析,我会编写简单的解析代码。检查开头的(,搜索到下一个,,提取子字符串。等等。

标签: c++ regex string parsing split


【解决方案1】:

您可以将正则表达式 \((\d+),(\d+),(\d+)\)std::sregex_iterator 一起使用。请注意,您必须转义 () 才能从字面上匹配它们。此外,使用原始文字字符串可以更轻松地使用正则表达式。

然后使用operator[] 提取每个匹配组。第 0 组始终是整个组,因此您需要第 1、2 和 3 组。

std::regex reg(R"(\((\d+),(\d+),(\d+)\))");
std::string str = "(1,2,1) (2,4,5) (1,4,3) (3,4,10) (3,6,2) (3,5,3) (6,7,6) (4,7,4)";
    
auto start = std::sregex_iterator(str.begin(), str.end(), reg);
auto end = std::sregex_iterator{};

for (std::sregex_iterator it = start; it != end; ++it)
{
     std::cout << "Node1 = " << (*it)[1] << ", Node2 = " << (*it)[2]
         << ", Distance = " << (*it)[3] << std::endl;         
}

这是demo

【讨论】:

    猜你喜欢
    • 2010-11-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-04
    • 2015-02-24
    • 2017-02-28
    • 1970-01-01
    相关资源
    最近更新 更多