How do I Search/Find and Replace in a standard str

2019-01-03 02:33发布

Is there a way to replace all occurrences of a substring with another string in std::string?

For instance:

void SomeFunction(std::string& str)
{
   str = str.replace("hello", "world"); //< I'm looking for something nice like this
}

标签: c++ replace std
10条回答
萌系小妹纸
2楼-- · 2019-01-03 02:55

The easiest way (offering something near what you wrote) is to use Boost.Regex, specifically regex_replace.

std::string has built in find() and replace() methods, but they are more cumbersome to work with as they require dealing with indices and string lengths.

查看更多
太酷不给撩
3楼-- · 2019-01-03 02:57
// Replace all occurrences of searchStr in str with replacer
// Each match is replaced only once to prevent an infinite loop
// The algorithm iterates once over the input and only concatenates 
// to the output, so it should be reasonably efficient
std::string replace(const std::string& str, const std::string& searchStr, 
    const std::string& replacer)
{
    // Prevent an infinite loop if the input is empty
    if (searchStr == "") {
        return str;
    }

    std::string result = "";
    size_t pos = 0;
    size_t pos2 = str.find(searchStr, pos);

    while (pos2 != std::string::npos) {
        result += str.substr(pos, pos2-pos) + replacer;
        pos = pos2 + searchStr.length();
        pos2 = str.find(searchStr, pos);
    }

    result += str.substr(pos, str.length()-pos);
    return result;
}
查看更多
相关推荐>>
4楼-- · 2019-01-03 02:58

Why not return a modified string?

std::string ReplaceString(std::string subject, const std::string& search,
                          const std::string& replace) {
    size_t pos = 0;
    while((pos = subject.find(search, pos)) != std::string::npos) {
         subject.replace(pos, search.length(), replace);
         pos += replace.length();
    }
    return subject;
}

If you need performance, here is an optimized function that modifies the input string, it does not create a copy of the string:

void ReplaceStringInPlace(std::string& subject, const std::string& search,
                          const std::string& replace) {
    size_t pos = 0;
    while((pos = subject.find(search, pos)) != std::string::npos) {
         subject.replace(pos, search.length(), replace);
         pos += replace.length();
    }
}

Tests:

std::string input = "abc abc def";
std::cout << "Input string: " << input << std::endl;

std::cout << "ReplaceString() return value: " 
          << ReplaceString(input, "bc", "!!") << std::endl;
std::cout << "ReplaceString() input string not changed: " 
          << input << std::endl;

ReplaceStringInPlace(input, "bc", "??");
std::cout << "ReplaceStringInPlace() input string modified: " 
          << input << std::endl;

Output:

Input string: abc abc def
ReplaceString() return value: a!! a!! def
ReplaceString() input string not modified: abc abc def
ReplaceStringInPlace() input string modified: a?? a?? def
查看更多
做自己的国王
5楼-- · 2019-01-03 02:58
#include <string>

using std::string;

void myReplace(string& str,
               const string& oldStr,
               const string& newStr) {
  if (oldStr.empty()) {
    return;
  }

  for (size_t pos = 0; (pos = str.find(oldStr, pos)) != string::npos;) {
    str.replace(pos, oldStr.length(), newStr);
    pos += newStr.length();
  }
}

The check for oldStr being empty is important. If for whatever reason that parameter is empty you will get stuck in an infinite loop.

But yeah use the tried and tested C++11 or Boost solution if you can.

查看更多
6楼-- · 2019-01-03 03:02
#include <iostream>
#include <string>

#include <boost/algorithm/string.hpp>
#include <boost/tokenizer.hpp>
#include <boost/foreach.hpp>

using namespace boost::algorithm;
using namespace std;
using namespace boost;

void highlighter(string terms, string text) {

    char_separator<char> sep(" ");
    tokenizer<char_separator<char> > tokens(terms, sep);

    BOOST_FOREACH(string term, tokens) {
        boost::replace_all(text, term, "<b>" + term + "</b>");
    }   
    cout << text << endl;
}

int main(int argc, char **argv)
{
    cout << "Search term highlighter" << endl;
    string text("I love boost library, and this is a test of boost library!");
    highlighter("love boost", text);
}

I love boost library, and this is a test of boost library!

查看更多
劳资没心,怎么记你
7楼-- · 2019-01-03 03:06

My templatized inline in-place find-and-replace:

template<class T>
int inline findAndReplace(T& source, const T& find, const T& replace)
{
    int num=0;
    typename T::size_t fLen = find.size();
    typename T::size_t rLen = replace.size();
    for (T::size_t pos=0; (pos=source.find(find, pos))!=T::npos; pos+=rLen)
    {
        num++;
        source.replace(pos, fLen, replace);
    }
    return num;
}

It returns a count of the number of items substituted (for use if you want to successively run this, etc). To use it:

std::string str = "one two three";
int n = findAndReplace(str, "one", "1");
查看更多
登录 后发表回答