How do I Search/Find and Replace in a standard string?
Why not implement your own replace?
void myReplace(std::string& str,
const std::string& oldStr,
const std::string& newStr)
{
std::string::size_type pos = 0u;
while((pos = str.find(oldStr, pos)) != std::string::npos){
str.replace(pos, oldStr.length(), newStr);
pos += newStr.length();
}
}
How to find and replace string?
Replace first match
Use a combination of std::string::find
and std::string::replace
.
Find the first match:
std::string s;
std::string toReplace("text to replace");
size_t pos = s.find(toReplace);
Replace the first match:
s.replace(pos, toReplace.length(), "new text");
A simple function for your convenience:
void replace_first(
std::string& s,
std::string const& toReplace,
std::string const& replaceWith
) {
std::size_t pos = s.find(toReplace);
if (pos == std::string::npos) return;
s.replace(pos, toReplace.length(), replaceWith);
}
Usage:
replace_first(s, "text to replace", "new text");
Demo.
Replace all matches
Define this O(n) method using std::string
as a buffer:
void replace_all(
std::string& s,
std::string const& toReplace,
std::string const& replaceWith
) {
std::string buf;
std::size_t pos = 0;
std::size_t prevPos;
// Reserves rough estimate of final size of string.
buf.reserve(s.size());
while (true) {
prevPos = pos;
pos = s.find(toReplace, pos);
if (pos == std::string::npos)
break;
buf.append(s, prevPos, pos - prevPos);
buf += replaceWith;
pos += toReplace.size();
}
buf.append(s, prevPos, s.size() - prevPos);
s.swap(buf);
}
Usage:
replace_all(s, "text to replace", "new text");
Demo.
Boost
Alternatively, use boost::algorithm::replace_all
:
#include <boost/algorithm/string.hpp>
using boost::replace_all;
Usage:
replace_all(s, "text to replace", "new text");
How to find and replace all occurrences of a substring in a string?
try the following
const std::string s = "*A";
const std::string t = "*A\n";
std::string::size_type n = 0;
while ( ( n = chartDataString.find( s, n ) ) != std::string::npos )
{
chartDataString.replace( n, s.size(), t );
n += t.size();
}
For string, find and replace
I can't help but wonder what algorithm strstr() implements. Given that these are fairly standard algorithms, it's entirely possible that a good implementation of strstr() uses one of them.
However there's no guarantee that strstr() implements an optimised algorithm or that the same algorithm is used from one platform to another.
How to replace all occurrences of a character in string?
std::string
doesn't contain such function but you could use stand-alone replace
function from algorithm
header.
#include <algorithm>
#include <string>
void some_func() {
std::string s = "example string";
std::replace( s.begin(), s.end(), 'x', 'y'); // replace all 'x' to 'y'
}
Performing a Regex search and Replace on a std::string
You need a global regular expression based substitution. Here're three ways to do this without any explicit loops (sure there're "implicit" loops in regex replace codes):
#include <iostream>
#include <string>
#include <regex> // std::regex
#include <pcrecpp.h> // pcrecpp::RE -- needs "-lpcrecpp -lpcre"
#include <pcrscpp.h> // pcrscpp::replace -- needs "-lpcrscpp -lpcre"
int main() {
std::regex std_rx (R"del(XYZ\d\d)del");
pcrecpp::RE pcrecpp_rx (R"del(XYZ\d\d)del");
pcrscpp::replace pcrscpp_rs(R"del(s/XYZ\d\d/A/g)del");
std::string str = " XYZ111 d-dxxxxxxx XYZ222 t-nyyyyyyyyy XYZ333 t-r ";
std::cout << "std::regex way: " << std::regex_replace (str, std_rx, "A") << std::endl
<< "pcrecpp way: ";
std::string buffer(str);
pcrecpp_rx.GlobalReplace("A", &buffer);
std::cout << buffer << std::endl
<< "pcrscpp way: ";
pcrscpp_rs.replace_store(str);
std::cout << pcrscpp_rs.replace_result << std::endl;
return 0;
}
Results:
std::regex way: A1 d-dxxxxxxx A2 t-nyyyyyyyyy A3 t-r
pcrecpp way: A1 d-dxxxxxxx A2 t-nyyyyyyyyy A3 t-r
pcrscpp way: A1 d-dxxxxxxx A2 t-nyyyyyyyyy A3 t-r
std::regex
needs C++11 features, and performs about twice slower than PCRE on simple patterns (see this answer), and I expect worse on more complicated ones, but doesn't require any additional libraries, as long as you use a C++11 compiler. PCRECPP is a PCRE C++ wrapper written by Google. PCRSCPP is my wrapper around PCRE that provides Perl-like regular expression based substitution capabilities, and hence is much more feature-rich than PCRECPP in this scope.
Replace part of a string with another string
There's a function to find a substring within a string (find
), and a function to replace a particular range in a string with another string (replace
), so you can combine those to get the effect you want:
bool replace(std::string& str, const std::string& from, const std::string& to) {
size_t start_pos = str.find(from);
if(start_pos == std::string::npos)
return false;
str.replace(start_pos, from.length(), to);
return true;
}
std::string string("hello $name");
replace(string, "$name", "Somename");
In response to a comment, I think replaceAll
would probably look something like this:
void replaceAll(std::string& str, const std::string& from, const std::string& to) {
if(from.empty())
return;
size_t start_pos = 0;
while((start_pos = str.find(from, start_pos)) != std::string::npos) {
str.replace(start_pos, from.length(), to);
start_pos += to.length(); // In case 'to' contains 'from', like replacing 'x' with 'yx'
}
}
my (find & replace) method is not working properly
This call of the member function replace
str.replace(i,i+x,replacement);
is incorrect. The second argument must specify the number of characters to be replaced.
The function should be defined the following way
std::string & Find_Replace( std::string &str, const std::string &substr, const std::string &replacement )
{
auto n1 = substr.length();
auto n2 = replacement.size();
for( auto pos = str.find( substr, 0 );
pos != std::string::npos;
pos = str.find(substr, pos ) )
{
str.replace( pos, n1, replacement );
pos += n2;
}
return str;
}
Here is a demonstrative program.
#include <iostream>
#include <string>
std::string & Find_Replace( std::string &str, const std::string &substr, const std::string &replacement )
{
auto n1 = substr.length();
auto n2 = replacement.size();
for( auto pos = str.find( substr, 0 );
pos != std::string::npos;
pos = str.find(substr, pos ) )
{
str.replace( pos, n1, replacement );
pos += n2;
}
return str;
}
int main()
{
std::string s( "Hello World!" );
std::cout << Find_Replace( s, "World", "C++ strings" ) << '\n';
return 0;
}
The program output is
Hello C++ strings!
How do I replace all instances of a string with another string?
The bug is in str.replace(start_pos, end_pos, to);
From the std::string doc at http://www.cplusplus.com/reference/string/string/replace/
string& replace ( size_t pos1, size_t n1, const string& str );
You are using an end-position, while the function expects a length.
So change to:
while((start_pos = str.find(from, start_pos)) != std::string::npos) {
str.replace(start_pos, from.length(), to);
start_pos += to.length(); // ...
}
Note: untested.
Related Topics
C/C++ Check If One Bit Is Set In, I.E. Int Variable
High Resolution Timer With C++ and Linux
Do Jagged Arrays Exist in C/C++
C++ Implicit Copy Constructor For a Class That Contains Other Objects
What Belongs in an Educational Tool to Demonstrate the Unwarranted Assumptions People Make in C/C++
What Exactly Do "Ib" and "Ub" Mean
C++0X Lambda Capture by Value Always Const
Rotate an Image Without Cropping in Opencv in C++
The Differences Between Initialize, Define, Declare a Variable
Does C++ Call Destructors For Global and Class Static Variables
How to Emulate Template≪Auto X≫