我想做一个与perl检查替换操作相当的c ++ 11:
sharedInstance
我可以毫无困难地进行更换:
my $v = "foo.rat"
if ( $v =~ s/\.rat$/.csv/ )
{
...
}
这给出了:
#include <iostream>
#include <string>
#include <regex>
int main()
{
std::string s{ "foo.rat" } ;
std::regex reg{ R"((.*)\.rat$)" } ;
s = std::regex_replace( s, reg, "$1.csv" ) ;
std::cout << s << std::endl ;
s = std::regex_replace( "foo.noo", reg, "$1.csv" ) ;
std::cout << s << std::endl ;
return 0 ;
}
请注意,对非匹配表达式的替换操作不会抛出错误(这正是我所期望的)。
查看regex_replace文档,对我来说,如何检查替换操作是否成功并不明显。我可以做一个字符串比较,但这似乎倒退了?
答案 0 :(得分:1)
只需将accepted answer添加到std::regex_iterator中即可。当可能发生多次更换时,这可能很方便。
迭代器std::regex_iterator
重复调用std::regex_search()
,直到找到所有匹配项。如果迭代器的开头位置和结尾位置相同,则找不到匹配项。
函数bool regex_replace(std::string &str, const std::string &re, const std::string& replacement)
实现了以下行为:
#include <iostream>
#include <regex>
bool regex_replace(std::string &str, const std::string &re, const std::string& replacement) {
std::regex regexp(re);
//Search regex
std::sregex_iterator begin = std::sregex_iterator(str.begin(), str.end(), regexp);
std::sregex_iterator end = std::sregex_iterator();
//replace using iterator
for (std::sregex_iterator i = begin; i != end; ++i)
str.replace(i->position(), i->length(), replacement);
//returns true if at least one match was found and replaced
return (begin != end);
}
此功能在原地运行。最后str
有替换项。仅当进行任何替换时,该函数才会返回true。
以下代码显示了如何使用它进行多次替换并检测是否进行了替换:
int main(int argc, char** argv) {
std::string rgx("[0-9]");
std::string str("0a1b2c3d4e5");
std::string replacement("?");
bool found = regex_replace(str, rgx, replacement);
std::cout << "Found any: " << (found ? "true" : "false") << std::endl;
std::cout << "string: " << str << std::endl;
return 0;
}
代码用引号'?'代替每个数字:
Found any: true
string: ?a?b?c?d?e?
答案 1 :(得分:0)
尝试找到与std::regex_match
或std::regex_search
的匹配项,检查某些内容是否匹配,然后使用std::string::replace
替换找到的字符串部分。这不应该导致性能下降。
答案 2 :(得分:0)
使用 std::regex_constants::format_no_copy
标志来改变 regex_replace()
的行为。看看下面的代码。
如果匹配失败,返回字符串现在将为空。
#include <iostream>
#include <string>
#include <regex>
int main()
{
std::string s{ "foo.rat" } ;
std::regex reg{ R"((.*)\.rat$)" } ;
auto rxMatchFlag = std::regex_constants::format_no_copy; //<---use this to modify the behavior of regex_replace when matching failed.
s = std::regex_replace( s, reg, "$1.csv", rxMatchFlag) ;
if(!s.empty()) std::cout << s << std::endl ;
else std::cout << "failed match" << std::endl;
s = std::regex_replace( "foo.noo", reg, "$1.csv", rxMatchFlag) ;
if(!s.empty()) std::cout << s << std::endl ;
else std::cout << "failed match" << std::endl;
return 0 ;
}
对于其他标志,查看它们 here
答案 3 :(得分:-1)
我不相信有任何直接的方法来确定是否有任何更换。
(不要将此与“成功/不成功”混淆,这不是完全相同的事情。)