How to Search/Find and Replace in a Standard String

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



Leave a reply



Submit