I am trying to make a simple piece of code work with boost::is_any_of and boost::replace_all_copy. The snippet is below:
std::string someString = "abc.def-ghi";
std::string toReplace = ".-";
std::string processedString = boost::replace_all_copy(someString, boost::is_any_of(toReplace), " ");
However, I get a compiler error that is too long to paste here. Could someone that has experience with these 2 functions please point out my error?
I don't think you can't. The three parameter version of boost::replace_all_copy takes the input string, a substitute string and the string to search for. What boost::is_any_of returns is a predicate functor.
What you probably want is boost::replace_if:
#include <boost/algorithm/string.hpp> // for is_any_of
#include <boost/range/algorithm/replace_if.hpp> // for replace_if
#include <string>
#include <iostream>
std::string someString = "abc.def-ghi";
std::string toReplace = ".-";
std::string processedString =
boost::replace_if(someString, boost::is_any_of(toReplace), ' ');
int main()
{
std::cout << processedString;
}
This modifies the original, so if you need to keep it, you can use boost::replace_copy_if:
#include <boost/algorithm/string.hpp>
#include <boost/range/algorithm/replace_copy_if.hpp>
#include <string>
#include <iostream>
#include <iterator> // for back_inserter
std::string someString = "abc.def-ghi";
std::string toReplace = ".-";
int main()
{
std::string processedString;
boost::replace_copy_if(someString,
std::back_inserter(processedString), boost::is_any_of(toReplace), ' ');
std::cout << processedString;
}
Hope that helps.
I am not overly familiar with that particular method but it appears that replace_all_copy wants just a replacement string rather than the result of is_any_of.
Glancing through the other options for string algorithms I noticed that there is a regex version that would also work:
#include <iostream>
#include <boost/algorithm/string.hpp>
#include <boost/algorithm/string/regex.hpp>
int main(int argc, char** argv) {
std::string someString = "abc.def-ghi";
std::cout << someString << std::endl;
std::string toReplace = "[.-]"; // character class that matches . and -
std::string replacement = " ";
std::string processedString =
boost::replace_all_regex_copy(someString, boost::regex(toReplace), replacement);
std::cout << processedString << std::endl;
return 0;
}
Output:
abc.def-ghi
abc def ghi
This does require linking against the boost regex lib. In my case, I built with:
g++ -L/usr/local/Cellar/boost/1.52.0/lib -lboost_regex-mt main.cpp
Related
After asking this question on SO, I realised that I needed to replace all matches within a string with another string. In my case, I want to replace all occurrences of a whitespace with `\s*' (ie. any number of whitespaces will match).
So I devised the following:
#include <string>
#include <regex>
int main ()
{
const std::string someString = "here is some text";
const std::string output = std::regex_replace(someString.c_str(), std::regex("\\s+"), "\\s*");
}
This fails with the following output:
error: no matching function for call to ‘regex_replace(const char*, std::regex, const char [4])
Working example: http://ideone.com/yEpgXy
Not to be discouraged, I headed over to cplusplus.com and found that my attempt actually matches the first prototype of the regex_replace function quite well, so I was surprised the compiler couldn't run it (for your reference: http://www.cplusplus.com/reference/regex/match_replace/)
So I thought I'd just run the example they provided for the function:
// regex_replace example
#include <iostream>
#include <string>
#include <regex>
#include <iterator>
int main ()
{
std::string s ("there is a subsequence in the string\n");
std::regex e ("\\b(sub)([^ ]*)"); // matches words beginning by "sub"
// using string/c-string (3) version:
std::cout << std::regex_replace (s,e,"sub-$2");
// using range/c-string (6) version:
std::string result;
std::regex_replace (std::back_inserter(result), s.begin(), s.end(), e, "$2");
std::cout << result;
// with flags:
std::cout << std::regex_replace (s,e,"$1 and $2",std::regex_constants::format_no_copy);
std::cout << std::endl;
return 0;
}
But when I run this I get the exact same error!
Working example: http://ideone.com/yEpgXy
So either ideone.com or cplusplus.com are wrong. Rather than bang my head against the wall trying to diagnose the errors of those far wiser than me I'm going to spare my sanity and ask.
You need to update your compiler to GCC 4.9.
Try using boosts regex as an alternative
regex_replace
Simple code C++ regex_replace only alphanumeric characters
#include <iostream>
#include <regex>
using namespace std;
int main() {
const std::regex pattern("[^a-zA-Z0-9.-_]");
std::string String = "!#!e-ma.il#boomer.zx";
// std::regex_constants::icase
// Only first
// std::string newtext = std::regex_replace( String, pattern, "X", std::regex_constants::format_first_only );
// All case insensitive
std::string newtext = std::regex_replace( String, pattern, "", std::regex_constants::icase);
std::cout << newtext << std::endl;
return 0;
}
Run https://ideone.com/CoMq3r
I'm looking for the best way to remove the first word from a std::string. This is what I have but I feel that this is overcompilicating things. What's the best and shortest way to do this? Thanks.
#include <string>
#include <iostream>
#include <sstream>
int main()
{
std::string str{"Where is everybody?"};
std::string first;
if (std::stringstream{str} >> first)
{
str.erase(str.begin(), str.begin() + first.size());
}
std::cout << str; // " is everybody?"
}
minor tweak, that leverages IO streams for the second half too :)
#include <string>
#include <iostream>
#include <sstream>
int main()
{
std::string str{"Where is everybody?"};
std::string first;
std::istringstream iss{str};
iss >> first;
std::ostringstream oss;
oss << iss.rdbuf();
std::cout << oss.str(); // " is everybody?"
}
You can do it without a stream: skip the initial spaces, locate the first space after that, walk to the next non-space, and use substr to get the rest of the string:
int i = 0;
while (isblank(str[i])) i++;
while (!isblank(str[i])) i++;
while (isblank(str[i])) i++;
str = str.substr(i);
Here is a demo on ideone.
Here is a solution using c++11's regex
#include <iostream>
#include <string>
#include <regex>
#include <iterator>
int main ()
{
std::string s ("there is a subsequence in the string\n");
std::regex e ("(\\s*)(\\w*)(.*)");
std::cout << std::regex_replace (s,e,"$1$3");
return 0;
}
You could try using string::substr() and string::find_first_of().
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;
}
}