【问题标题】:std::regex search and replacestd::regex 搜索和替换
【发布时间】:2016-07-21 10:24:45
【问题描述】:

我需要帮助正则表达式与以下源字符串一起正常工作:

<path d="M 1434.9,982.0 L 1461.3,982.0  L 1461.3,1020.5  L 1434.9,1020.5 z " stroke-width="1" stroke="#008000" fill="none"/>

在这一行,我需要调整stroke-widthstroke 的值,而不影响其余内容。

到目前为止,我分两步执行此操作,首先替换 stroke 值,然后替换 stroke-width 值,这是我得到奇怪结果的地方,见下文。

片段

string s("<path d=\"M 1434.9,982.0 L 1461.3,982.0  L 1461.3,1020.5  L 1434.9,1020.5 z \" stroke-width=\"1\" stroke=\"#008000\" fill=\"none\"/>");                   
std::regex re("stroke=\".+\" ");
cout << "0. " << s << endl;
s = std::regex_replace(s, re, "stroke=\"#00FF00\" ");
cout << "1. " << s << endl;
re = "stroke-width=\".+\" .*?";
s = std::regex_replace(s, re, "stroke-width=\"3\" ");
cout << "2. " << s << endl;

输出

0.     <path d="M 1434.9,982.0 L 1461.3,982.0  L 1461.3,1020.5  L 1434.9,1020.5 z " stroke-width="1" stroke="#008000" fill="none"/>
1.     <path d="M 1434.9,982.0 L 1461.3,982.0  L 1461.3,1020.5  L 1434.9,1020.5 z " stroke-width="1" stroke="#00FF00" fill="none"/>
2.     <path d="M 1434.9,982.0 L 1461.3,982.0  L 1461.3,1020.5  L 1434.9,1020.5 z " stroke-width="3" fill="none"/>

除了2. 字符串输出中,stroke 字段消失了之外,这几乎就是我要查找的内容!

我目前正在使用std::regex,但我也对boost::regex 持开放态度。 感谢任何关于此的指针。

【问题讨论】:

    标签: regex c++11 boost


    【解决方案1】:

    .+ 将匹配尽可能多的字符,因此如果字符串后面有更多引号,它将消耗右引号及更多字符。请改用非贪婪版本.+?

    此外,最后一个模式中的尾随 .*? 不会匹配任何内容,可以删除。

    【讨论】:

      【解决方案2】:

      我刚刚尝试了另一种方法,使正则表达式不那么贪婪,这在这种情况下有效。

      // changing the 1st regex to
      regex re("stroke=\".+?\" ");
      
      // and the 2nd to
      re = "stroke-width=\".+?\" ";
      

      这次给出了正确的输出:

      0.     <path d="M 1434.9,982.0 L 1461.3,982.0  L 1461.3,1020.5  L 1434.9,1020.5 z " stroke-width="1" stroke="#008000" fill="none"/>
      1.     <path d="M 1434.9,982.0 L 1461.3,982.0  L 1461.3,1020.5  L 1434.9,1020.5 z " stroke-width="1" stroke="#00FF00" fill="none"/>
      2.     <path d="M 1434.9,982.0 L 1461.3,982.0  L 1461.3,1020.5  L 1434.9,1020.5 z " stroke-width="3" stroke="#00FF00" fill="none"/>
      

      【讨论】:

        【解决方案3】:

        您可以在一个正则表达式中替换这两个值。

        ^(.*stroke-width=)(.*?)(\s.*stroke=["'])(.*?)(["'].*)$
        

        例子:

        std::string text = R"(<path d="M 1434.9,982.0 L 1461.3,982.0  L 1461.3,1020.5  L 1434.9,1020.5 z " stroke-width="1" stroke="#008000" fill="none"/>)";
        std::string result;
        
        char buff[100];
        snprintf(buff, sizeof(buff), "$1\"%s\"$3%s$5", "5","#000000");
        std::string replacement_text = buff;
        
        std::regex re(R"(^(.*stroke-width=)(.*?)(\s.*stroke=["'])(.*?)(["'].*)$)",
                   std::regex_constants::icase);
        
        result = std::regex_replace(text, re, replacement_text);
        
        cout << result << endl;
        

        代码将发出:

        <path d="M 1434.9,982.0 L 1461.3,982.0  L 1461.3,1020.5  L 1434.9,1020.5 z " stroke-width="5" stroke="#000000" fill="none"/>
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2015-12-28
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多