代码之家  ›  专栏  ›  技术社区  ›  Adam Tegen

如何在标准字符串中搜索/查找和替换?

  •  86
  • Adam Tegen  · 技术社区  · 15 年前

    是否有方法将子字符串的所有出现项替换为中的另一个字符串? std::string ?

    例如:

    void SomeFunction(std::string& str)
    {
       str = str.replace("hello", "world"); //< I'm looking for something nice like this
    }
    
    10 回复  |  直到 6 年前
        1
  •  69
  •   jotik    8 年前

    为什么不实现自己的替换呢?

    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();
      }
    }
    
        2
  •  146
  •   TheNamelessOne    6 年前
    #include <boost/algorithm/string.hpp> // include Boost, a C++ library
    ...
    std::string target("Would you like a foo of chocolate. Two foos of chocolate?");
    boost::replace_all(target, "foo", "bar");
    

    这是 the official documentation 关于RePasy-ALL。

        3
  •  22
  •   Zaid    7 年前

    在C++ 11中,您可以通过调用 regex_replace :

    #include <string>
    #include <regex>
    
    using std::string;
    
    string do_replace( string const & in, string const & from, string const & to )
    {
      return std::regex_replace( in, std::regex(from), to );
    }
    
    string test = "Remove all spaces";
    std::cout << do_replace(test, " ", "") << std::endl;
    

    输出:

    Removeallspaces
    
        4
  •  15
  •   Czarek Tomczak    11 年前

    为什么不返回修改后的字符串?

    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;
    }
    

    如果需要性能,这里有一个修改输入字符串的优化函数,它不会创建字符串的副本:

    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();
        }
    }
    

    测验:

    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;
    

    输出:

    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
  •  6
  •   Marius    11 年前

    我的模板化内联就地查找和替换:

    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;
    }
    

    它返回被替换的项数的计数(如果要连续运行此项,则使用此项等)。要使用它:

    std::string str = "one two three";
    int n = findAndReplace(str, "one", "1");
    
        6
  •  3
  •   Alan    15 年前

    最简单的方法(提供接近你所写内容的内容)是使用 Boost.Regex ,具体地说 regex_replace .

    std::string内置find()和replace()方法,但它们在处理索引和字符串长度时更麻烦。

        7
  •  3
  •   Daniel Ryan    11 年前

    我相信这会奏效的。 它以const char*作为参数。

    //params find and replace cannot be NULL
    void FindAndReplace( std::string& source, const char* find, const char* replace )
    {
       //ASSERT(find != NULL);
       //ASSERT(replace != NULL);
       size_t findLen = strlen(find);
       size_t replaceLen = strlen(replace);
       size_t pos = 0;
    
       //search for the next occurrence of find within source
       while ((pos = source.find(find, pos)) != std::string::npos)
       {
          //replace the found string with the replacement
          source.replace( pos, findLen, replace );
    
          //the next line keeps you from searching your replace string, 
          //so your could replace "hello" with "hello world" 
          //and not have it blow chunks.
          pos += replaceLen; 
       }
    }
    
        8
  •  2
  •   Kevin Duraj    8 年前
    #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);
    }
    

    促进 图书馆,这是对 促进 图书馆!

        9
  •  1
  •   Björn Ganster    7 年前
    // 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;
    }
    
        10
  •  0
  •   ericcurtin    7 年前
    #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();
      }
    }
    

    检查oldstr是否为空很重要。如果由于任何原因,该参数为空,您将陷入无限循环。

    但是,如果可以的话,请使用经过考验的C++ 11或Boost解决方案。