【问题标题】:C++ character replaceC++ 字符替换
【发布时间】:2009-11-30 15:13:45
【问题描述】:

替换字符串中字符的最佳方法是什么?

具体来说:

"This,Is A|Test" ----> "This_Is_A_Test"

我想替换所有逗号、空格和“|”带下划线。

(我可以使用 Boost。)

【问题讨论】:

  • 这是一个std::string类的字符串,还是一个以\0结尾的char类型的数组?
  • 我认为各种 replace_if 答案,例如本叔叔,很好。但是,一个一般性评论是:如果您要替换字符以获得可以安全使用的东西,例如作为文件名,您应该列出允许的字符并替换其他所有字符,而不是相反。这样你就不会对你没有想到的任何奇怪的输入感到惊讶。

标签: c++ regex string boost


【解决方案1】:

您可以使用标准的replace_if 算法,除了谓词相当复杂(要与当前的 C++ 标准内联表达并且没有 lambda)。

你可以自己写,或者使用 boost 字符串算法中的is_any_of,所以:

#include <algorithm>
#include <string>
#include <boost/algorithm/string/classification.hpp>
#include <iostream>

int main()
{
    std::string s("This,Is A|Test");
    std::replace_if(s.begin(), s.end(), boost::is_any_of(", |"), '_');
    std::cout << s << '\n';
}

【讨论】:

    【解决方案2】:

    您可以使用 STL 算法 replace_if

    【讨论】:

      【解决方案3】:

      正如其他答案所示,您可以使用各种 replace 方法。但是,这些方法的缺点是要多次扫描字符串(每个字符一次)。如果您关心速度,我建议您使用自己的替换方法:

      void beautify(std::string &s) {
          int i;
          for (i = 0; i < s.length(); ++i) {
              switch (s[i]) {
              case ' ':
              case ',':
              case '|':
                  s[i] = '_';
              }
          }
      }
      

      【讨论】:

      • 单行替换方法很好,但您的解决方案也很有效
      • 一行替换肯定更好(我认为您至少需要行),但效率不高。
      • 我认为replace_if 不会多次扫描字符串。
      【解决方案4】:

      编辑:正如Space_C0wb0y 所说,replace_if 肯定更好。这是一些simpler 示例代码:

      #include <string>
      #include <iostream>
      #include <algorithm>
      using namespace std;
      
      bool isBad(char c)
      {
       const string bad_chars = "|, ";
       return (bad_chars.find(c) != string::npos);
      }
      
      int main()
      {
       string str = "This,Is A|Test";
      
       // Replace!
       replace_if(str.begin(),str.end(),isBad,'_');
      
       cout<<str<<endl; 
       return 0;
      }
      

      旧答案:

      std::replacestd::find_first_of 一起使用

      【讨论】:

        【解决方案5】:

        boost::replace_all(s, old, new);

        【讨论】:

          【解决方案6】:

          C++ 标准库也可以在不使用 BOOST 的情况下访问这些函数。请参阅replace C++ Reference。这是最好的方法吗?我想这有待讨论。要替换多个/不同的字符,您可能需要多次调用 replace。

          #include <string>
              string& replace( size_type index, size_type num, const string& str );
              string& replace( size_type index1, size_type num1, const string& str, size_type index2, size_type num2 );
              string& replace( size_type index, size_type num, const Char* str );
              string& replace( size_type index, size_type num1, const Char* str, size_type num2 );
              string& replace( size_type index, size_type num1, size_type num2, Char ch);
          
              string& replace( iterator start, iterator end, const string& str );
              string& replace( iterator start, iterator end, const Char* str );
              string& replace( iterator start, iterator end, const Char* str, size_type num );
              string& replace( iterator start, iterator end, size_type num, Char ch );
              string& replace( iterator start, iterator end, input_iterator start2, input_iterator end2 );
          

          Example program:

          // replacing in a string
          #include <iostream>
          #include <string>
          using namespace std;
          
          int main ()
          {
            string base="this is a test string.";
            string str2="n example";
            string str3="sample phrase";
            string str4="useful.";
          
            // function versions used in the same order as described above:
          
            // Using positions:                 0123456789*123456789*12345
            string str=base;                // "this is a test string."
            str.replace(9,5,str2);          // "this is an example string."
            str.replace(19,6,str3,7,6);     // "this is an example phrase."
            str.replace(8,10,"just all",6); // "this is just a phrase."
            str.replace(8,6,"a short");     // "this is a short phrase."
            str.replace(22,1,3,'!');        // "this is a short phrase!!!"
          
            // Using iterators:                      0123456789*123456789*
            string::iterator it = str.begin();   //  ^
            str.replace(it,str.end()-3,str3);    // "sample phrase!!!"
            str.replace(it,it+6,"replace it",7); // "replace phrase!!!"
            it+=8;                               //          ^
            str.replace(it,it+6,"is cool");      // "replace is cool!!!"
            str.replace(it+4,str.end()-4,4,'o'); // "replace is cooool!!!"
            it+=3;                               //             ^
            str.replace(it,str.end(),str4.begin(),str4.end());
                                                 // "replace is useful."
            cout << str << endl;
            return 0;
          }
          

          【讨论】:

          • 替换方法只是替换一个字符(范围),而不是所有出现的东西,所以我想说它确实对这项任务没有太大帮助:)
          • 罗杰。这就是为什么我说它需要运行不止一次。是否是最好的方法,取决于开发人员
          • 实际上你可能会让水变得更浑浊。 string::replace 用于将单个范围替换为另一个字符串(或字符)。 OP 只想替换单个字符,因此您可以使用 operator[] 代替重量级替换方法,它允许您“替换”单个字符的值。
          【解决方案7】:

          我正在写这篇文章时,Space_C0wb0y 发布了他的答案,这是您问题的正确答案。这有点复杂,但可以处理更多可能的替换。

          (抱歉,未编译/测试)

          class MyReplacer
          {
            friend std::ostream& operator<<(std::ostream& os, const MyReplacer& Repl);
            public:
              MyReplacer(char c) : ch(c) {}
            private:
              char ch;
          };
          
          std::ostream& operator<<(std::ostream& os, const MyReplacer& Repl)
          {
            switch (Repl.ch)
            {
              case '|':
              case ' ':
              case ',': os << '_'; break;
              default: os << Repl.ch;
            }
            return os;
          }
          
          
          std::ostringstream oss;
          std::copy(str.begin(), str.end(), std::ostream_iterator<MyReplacer>(oss));
          std::string result = oss.str();
          

          【讨论】:

            猜你喜欢
            • 2011-06-08
            • 2013-04-01
            • 2010-12-06
            • 2013-05-26
            • 1970-01-01
            • 1970-01-01
            • 2012-09-02
            • 2014-04-11
            相关资源
            最近更新 更多