#include <iostream>
#include <iterator>
#include <regex>
#include <string>
std::string ty(std::string text){
if(text == "brown")
return "true";
else
return "qw";
}
int main()
{
std::string text = "Quick $brown fox";
std::cout << '\n' << std::regex_replace(text, std::regex(R"(\\$(.*))"), ty("$&")) << '\n';
}
i use c++11 . I try without if worked but with if don't work ? i don't know what to do
There's a lot of different things wrong with the original code.
Firstly here's some working code
#include <iostream>
#include <iterator>
#include <regex>
#include <string>
std::string ty(std::string text){
if(text == "brown")
return "true";
else
return "qw";
}
int main()
{
std::string text = "Quick $brown fox";
std::smatch m;
if (std::regex_search(text, m, std::regex(R"(\$([[:alpha:]][[:alnum:]]*))")))
{
std::cout << '\n' << ty(std::string(m[1].first, m[1].second)) << '\n';
}
else
{
std::cout << "\nno match\n";
}
}
Some things that were wrong with the original code
Firstly the function being called was wrong. Use std::regex_search to search for matches in a string. Capture the results in an std::smatch object and then use those results to call the ty function.
The regex was wrong in two different ways. Firstly \\ is wrong because you are using a raw string literal, so only a single backslash is required. Secondly (.*) is wrong because that will match the entire rest of the string. You only want to match the word following the dollar. I've used ([[:alpha:]][[:alnum:]]*) instead. That might not be exactly what you want but it works for this example. You can modify it if you want.
Related
I am having a problem with boost regex in cpp. I want to match a string like
"Hello %world% regex %cpp%" and expected string output is world, cpp
Can somebody suggest a regex for this
Thanks
Anil
I personally prefer "\\%([^\\%]*)\\%" (or as a raw string R"r(\%([^\%]*)\%)r")
It doesn't rely on non-greedy qualifiers
Which is essentially
one percent character \\%
any amount of non-percent characters [^\\%]*
one percent character \\%
I know this is tagged boost but here's a solution with std::regex
#include <string>
#include <regex>
#include <iostream>
int main()
{
using namespace std;
string source = "Hello %world%";
regex match_percent_enclosed (R"_(\%([^\%]*)\%)_");
smatch between_percent;
bool found_match = regex_search(source,between_percent,match_percent_enclosed);
if(found_match && between_percent.size()>1)
cout << "found: \"" << between_percent[1].str() << "\"." << endl;
else
cout << "no match found." << endl;
}
you may get some idea
%(.+?)%
Result:
Match 1
1. world
Match 2
1. cpp
You can use this regex \%(.*?)\%smallest group
Online regex: https://regex101.com/r/dSCE2a/2
And for the code with boost
#include <iostream>
#include <cstdlib>
#include <boost/regex.hpp>
using namespace std;
int main()
{
boost::cmatch mat;
boost::regex reg( "\\%(.*?)\\%" );
char szStr[] = "Hello %world% regex %cpp%";
char *where = szStr;
while (regex_search(where, mat, reg))
{
cout << mat[1] << endl; // 0 for whole match, 1 for sub
where = (char*)mat[0].second;
}
}
I have a problem with boost::replace_all. My string looks like:
""Date"":1481200838,""Message"":""
And I would like it to look like:
"Date":1481200838,"Message":"
So i would like to replace "" with single ":
boost::replace_all(request_json_str, """", """);
But it doesn't work at all. Same with:
boost::replace_all(request_json_str, "\"\"", "\"");
How could I make this to work?
You need to correctly escape the " character in your call to boost::replace_all!
// Example program
#include <iostream>
#include <string>
#include <algorithm>
#include <boost/algorithm/string/replace.hpp>
int main()
{
std::string msg("\"Date\"\":1481200838,\"\"Message\"\":\"");
boost::replace_all(msg, "\"\"", "\"");
std::cout << msg << std::endl;
}
The boost::replace_all(request_json_str, "\"\"", "\"") already in your answer is the correct way to handle this using boost::replace_all: http://coliru.stacked-crooked.com/a/af7cbc753e16cf4f
I wanted to post an additional answer to say that given auto request_json_str = "\"\"Date\"\":1481200838,\"\"Message\"\":\"\""s the repeated quotations could also be removed without Boost (though not quite so eloquently, using unique, distance, and string::resize):
request_json_str.resize(distance(begin(request_json_str), unique(begin(request_json_str), end(request_json_str), [](const auto& a, const auto& b){ return a == '"' && b == '"'; })));
The best I can come up with is:
#include <boost/algorithm/string/replace.hpp>
#include <boost/regex.hpp>
#include <iostream>
using namespace std;
int main() {
string dog = "scooby-doo";
boost::regex pattern("(\\w+)-doo");
boost::smatch groups;
if (boost::regex_match(dog, groups, pattern))
boost::replace_all(dog, string(groups[1]), "scrappy");
cout << dog << endl;
}
with output:
scrappy-doo
.. is there a simpler way of doing this, that doesn't involve doing two distinct searches? Maybe with the new C++11 stuff (although I'm not sure that it's compatible with gcc atm?)
std::regex_replace should do the trick. The provided example is pretty close to your problem, even to the point of showing how to shove the answer straight into cout if you want. Pasted here for posterity:
#include <iostream>
#include <iterator>
#include <regex>
#include <string>
int main()
{
std::string text = "Quick brown fox";
std::regex vowel_re("a|e|i|o|u");
// write the results to an output iterator
std::regex_replace(std::ostreambuf_iterator<char>(std::cout),
text.begin(), text.end(), vowel_re, "*");
// construct a string holding the results
std::cout << '\n' << std::regex_replace(text, vowel_re, "[$&]") << '\n';
}
I have these variables:
boost::regex re //regular expression to use
std::string stringToChange //replace this string
std::string newValue //new value that is going to replace the stringToChange depending on the regex.
I only want to replace the first occurrence of it only.
Thanks fellas.
EDIT: I've found this:
boost::regex_replace(stringToChange, re, boost::format_first_only);
but it says the function does not exists, I'm guessing the parameters are incorrect at the moment.
Here is an example of basic usage:
#include <iostream>
#include <string>
#include <boost/regex.hpp>
int main(){
std::string str = "hellooooooooo";
std::string newtext = "o Bob";
boost::regex re("ooooooooo");
std::cout << str << std::endl;
std::string result = boost::regex_replace(str, re, newtext);
std::cout << result << std::endl;
}
Output
hellooooooooo
hello Bob
Make sure you are including <boost/regex.hpp> and have linked to the boost_regex library.
I have some difficulties in understanding if-then-else conditionals in regular expressions.
After reading If-Then-Else Conditionals in Regular Expressions I decided to write a simple test. I use C++, Boost 1.38 Regex and MS VC 8.0.
I have written this program:
#include <iostream>
#include <string>
#include <boost/regex.hpp>
int main()
{
std::string str_to_modify = "123";
//std::string str_to_modify = "ttt";
boost::regex regex_to_search ("(\\d\\d\\d)");
std::string regex_format ("(?($1)$1|000)");
std::string modified_str =
boost::regex_replace(
str_to_modify,
regex_to_search,
regex_format,
boost::match_default | boost::format_all | format_no_copy );
std::cout << modified_str << std::endl;
return 0;
}
I expected to get "123" if str_to_modify has "123" and to get "000" if I str_to_modify has "ttt". However I get ?123123|000 in the first case and nothing in second one.
Coluld you tell me, please, what is wrong with my test?
The second example that still doesn't work :
#include <iostream>
#include <string>
#include <boost/regex.hpp>
int main()
{
//std::string str_to_modify = "123";
std::string str_to_modify = "ttt";
boost::regex regex_to_search ("(\\d\\d\\d)");
std::string regex_format ("(?1foo:bar");
std::string modified_str =
boost::regex_replace(str_to_modify, regex_to_search, regex_format,
boost::match_default | boost::format_all | boost::format_no_copy );
std::cout << modified_str << std::endl;
return 0;
}
I think the format string should be (?1$1:000) as described in the Boost.Regex docs.
Edit: I don't think regex_replace can do what you want. Why don't you try the following instead? regex_match will tell you whether the match succeeded (or you can use match[i].matched to check whether the i-th tagged sub-expression matched). You can format the match using the match.format member function.
#include <iostream>
#include <string>
#include <boost/regex.hpp>
int main()
{
boost::regex regex_to_search ("(\\d\\d\\d)");
std::string str_to_modify;
while (std::getline(std::cin, str_to_modify))
{
boost::smatch match;
if (boost::regex_match(str_to_modify, match, regex_to_search))
std::cout << match.format("foo:$1") << std::endl;
else
std::cout << "error" << std::endl;
}
}