std :: regex搜索和替换

时间:2016-04-01 14:44:30

标签: regex c++11 boost

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

<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。 感谢关于此的任何指示。

3 个答案:

答案 0 :(得分:1)

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

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

答案 1 :(得分:0)

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

// 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"/>

答案 2 :(得分:0)

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

^(.*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"/>