【问题标题】:Matching on varying number of lines with C++ std::regex_replace使用 C++ std::regex_replace 匹配不同数量的行
【发布时间】:2018-01-29 11:09:57
【问题描述】:

我可以使用C++ std::regex 提取带有此片段的四行字符串:

  std::regex table("(<table id.*\n.*\n.*\n.*>)");
  const std::string format="$&";
  std::cout <<
     std::regex_replace(tidy_string(/* */)
        ,table
        ,format
        ,std::regex_constants::format_no_copy
        |std::regex_constants::format_first_only
        )
     << '\n';

tidy_string() 返回一个std::string 并且代码产生这个输出:

<table id="creditPolicyTable" class=
                              "table table-striped table-condensed datatable top-bold-border bottom-border"
                              summary=
                              "This table of Credit Policy gives credit information (column headings) for list of exams (row headings).">

如何匹配具有不同行数而不是恰好四行的文本?例如:

<table id="creditPolicyTable" summary=
                              "This table of Credit Policy gives credit information (column headings) for list of exams (row headings).">

或:

<table id="creditPolicyTable"
    class="table table-striped table-condensed datatable top-bold-border bottom-border"
   summary="This table of Credit Policy gives credit information (column headings) for list of exams (row headings)."
 more="x"
 even_more="y">

【问题讨论】:

  • 您可以只使用(&lt;table id[^&gt;]*?&gt;)。这将匹配第一个 &gt; 之前的所有内容,因此为您提供 &lt;table&gt; 选项卡的内容(假设里面没有转义的 &gt; 字符)。一般来说,我认为使用正则表达式解析 XML/HTML 不是最好的方法,您是否考虑过使用 XML 解析器(例如 libxml2)?
  • 后面的那些标签,你的意思是写成"
    "之类的吗?
  • 顺便说一句,您在上面使用的 .* 运算符是“贪婪的”,即它们尝试匹配尽可能多的字符。如果您有一个非常长的文件,其中包含许多“
  • ”标签,这可能是一个问题。
  • 我觉得有必要链接到这个很棒的 SO 答案,并希望您找到解析 xml 数据的替代方法。 stackoverflow.com/questions/1732348/…

标签: c++ regex c++17


【解决方案1】:

您应该使用 std::regex_search 并懒惰地搜索除 '>' 字符之外的任何内容。像这样:

#include <iostream>
#include <regex>

int main() {
  std::string lines[] = {"<table id=\"creditPolicyTable\" class=\"\
table table-striped -table-condensed datatable top-bold-border bottom-border\"\
summary=\
\"This table of Credit Policy gives credit information (column headings) for list of exams (row headings).\">",
               "<table id=\"creditPolicyTable\" summary=\
               \"This table of Credit Policy gives credit information (column headings) for list of exams (row headings).\"\
               more=\"x\"\
               even_more=\"y\">"};
  std::string result;
  std::smatch table_match;

  std::regex table_regex("<table\\sid=[^>]+?>");

  for (const auto& line : lines){
    if (std::regex_search(line, table_match, table_regex)) {
      for (size_t i = 0; i < table_match.size(); ++i)
        std::cout << "Match found " << table_match[i] << '\n';
    }
  }
}

【讨论】:

    猜你喜欢
    相关资源
    最近更新 更多
    热门标签