प्रतिस्थापन के साथ किसी अन्य प्रतिस्थापन C ++ से प्रतिस्थापित करें


91

मैं C ++ में किसी अन्य स्ट्रिंग के साथ स्ट्रिंग में एक प्रतिस्थापन की जगह कैसे ले सकता हूं, मैं किन कार्यों का उपयोग कर सकता हूं?

eg: string test = "abc def abc def";
test.replace("abc", "hij").replace("def", "klm"); //replace occurrence of abc and def with other substring

5
बहुत अधिक stackoverflow.com/questions/3418231/… का एक डुप्लिकेट है जिसमें स्वीकृत उत्तर में अधिक मजबूत समाधान है।
dave-holm

जवाबों:


77

ऐसा करने के लिए C ++ में कोई भी अंतर्निहित फ़ंक्शन नहीं है। यदि आप किसी अन्य के साथ एक-स्ट्रिंग के सभी उदाहरणों को बदलने के लिए चाहते हैं, तो आपको कॉल intermixing करके कर सकते हैं string::findऔर string::replace। उदाहरण के लिए:

size_t index = 0;
while (true) {
     /* Locate the substring to replace. */
     index = str.find("abc", index);
     if (index == std::string::npos) break;

     /* Make the replacement. */
     str.replace(index, 3, "def");

     /* Advance index forward so the next iteration doesn't pick it up as well. */
     index += 3;
}

इस कोड की अंतिम पंक्ति में, मैंने indexउस स्ट्रिंग की लंबाई बढ़ा दी है जिसे स्ट्रिंग में डाला गया है। इस विशेष उदाहरण में - के "abc"साथ प्रतिस्थापित करना "def"- यह वास्तव में आवश्यक नहीं है। हालाँकि, अधिक सामान्य सेटिंग में, स्ट्रिंग को छोड़ना महत्वपूर्ण है जिसे अभी-अभी बदला गया है। उदाहरण के लिए, यदि आप नव-प्रतिस्थापित स्ट्रिंग खंड पर लंघन के बिना, के "abc"साथ बदलना चाहते हैं, तो "abcabc"यह कोड लगातार नए-प्रतिस्थापित स्ट्रिंग्स के कुछ हिस्सों को बदल देगा जब तक कि मेमोरी समाप्त नहीं हो जाती। स्वतंत्र रूप से, उन नए पात्रों को वैसे भी छोड़ना थोड़ा तेज़ हो सकता है, क्योंकि ऐसा करने से string::findफ़ंक्शन द्वारा कुछ समय और प्रयास बचता है।

उम्मीद है की यह मदद करेगा!


6
मुझे विश्वास नहीं है कि आपको सूचकांक में वृद्धि करने की आवश्यकता होगी क्योंकि आपने पहले ही डेटा को बदल दिया है इसलिए इसे वैसे भी नहीं लेंगे।
rossb83

1
@ एडिआकापी यदि इसे एक सामान्य उद्देश्य फ़ंक्शन में बदल दिया जाता है, तो यह एक अनंत लूप में नहीं फंस जाएगा क्योंकि यह indexस्ट्रिंग की जगह के पिछले हिस्से की खोज स्थिति को आगे बढ़ाता है ।
टिम आर।

1
@TimR। आप सही हैं, मैं rossb83 पर प्रतिक्रिया दे रहा था, जो बताता है कि सूचकांक की वृद्धि अनावश्यक है। सिर्फ गलत सूचना को रोकने की कोशिश कर रहा था। तो बाकी सभी के लिए: बदली हुई स्ट्रिंग की लंबाई द्वारा सूचकांक को बढ़ाना (इस मामले में 3) आवश्यक है । इसे कोड नमूने से न निकालें।
एदियाकापी

@FrozenKiwi मुझे यह सुनकर आश्चर्य हुआ। क्या आप निश्चित हैं कि ऐसा ही है?
templatetypedef

1
@JulianCienfuegos मैंने इसे संबोधित करने का उत्तर अपडेट किया है - यह इंगित करने के लिए धन्यवाद! (इसके अलावा, Aidiakapi कोई और है ... निश्चित नहीं है कि वह कौन है।)
templatetypedef

68

बूस्ट स्ट्रिंग एल्गोरिदम लाइब्रेरी तरीका:

#include <boost/algorithm/string/replace.hpp>

{ // 1. 
  string test = "abc def abc def";
  boost::replace_all(test, "abc", "hij");
  boost::replace_all(test, "def", "klm");
}


{ // 2.
  string test = boost::replace_all_copy
  (  boost::replace_all_copy<string>("abc def abc def", "abc", "hij")
  ,  "def"
  ,  "klm"
  );
}

4
जे। मुझे सभी सबस्ट्रिंग को बदलने के लिए बढ़ावा देने की आवश्यकता है।
जोहान्स ओवरमैन

2
बूस्ट ज्यादातर ओवरकिल होता है।
कोनराड


43

मुझे लगता है कि सभी समाधान विफल हो जाएंगे यदि प्रतिस्थापित स्ट्रिंग की लंबाई स्ट्रिंग की लंबाई से अलग है। ("abc" की खोज करें और "xxxxxx" द्वारा प्रतिस्थापित करें) एक सामान्य दृष्टिकोण हो सकता है:

void replaceAll( string &s, const string &search, const string &replace ) {
    for( size_t pos = 0; ; pos += replace.length() ) {
        // Locate the substring to replace
        pos = s.find( search, pos );
        if( pos == string::npos ) break;
        // Replace by erasing and inserting
        s.erase( pos, search.length() );
        s.insert( pos, replace );
    }
}

41
str.replace(str.find(str2),str2.length(),str3);

कहाँ पे

  • str आधार स्ट्रिंग है
  • str2 खोजने के लिए उप स्ट्रिंग है
  • str3 प्रतिस्थापन प्रतिस्थापन है

3
यह केवल पहली घटना की जगह लेता है, है ना?
jpo38

4
मेरा सुझाव है कि str.find (str2) के परिणाम को सुनिश्चित करने के बराबर नहीं है std :: string :: npos auto found = str.find (str2); if (पाया! = std :: string :: npos) str.replace (पाया, str2.length (), str3);
ज्यॉफ लेंटस्च

1
मैं इस के साथ पूरे आवेदन को लिखने का इरादा नहीं कर रहा था, लेकिन इनपुट पर कोई भी जांच किए बिना इस के मामले अपरिभाषित हैं ....
जेफ़ ज़ाचेर

19

प्रतिस्थापनों को बदलना उतना कठिन नहीं होना चाहिए।

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

if (search.empty()) { return; }खाली 'खोज' पास करने पर अनंत लूप से बचने के लिए चेक जोड़ने की आवश्यकता है ।
आईओएस-प्रोग्रामर

रिप्लेस किए गए रिप्लेसमेंट स्ट्रिंग फ़ंक्शन - काम नहीं किया गया। लेकिन उत्तर बोला: str.replace (str.find (str2), str2.length (), str3); बस सरल और अच्छी तरह से काम करता है।
KAMIKAZE

5
using std::string;

string string_replace( string src, string const& target, string const& repl)
{
    // handle error situations/trivial cases

    if (target.length() == 0) {
        // searching for a match to the empty string will result in 
        //  an infinite loop
        //  it might make sense to throw an exception for this case
        return src;
    }

    if (src.length() == 0) {
        return src;  // nothing to match against
    }

    size_t idx = 0;

    for (;;) {
        idx = src.find( target, idx);
        if (idx == string::npos)  break;

        src.replace( idx, target.length(), repl);
        idx += repl.length();
    }

    return src;
}

चूंकि यह stringकक्षा का सदस्य नहीं है , इसलिए यह आपके उदाहरण के रूप में काफी अच्छे वाक्यविन्यास की अनुमति नहीं देता है, लेकिन निम्नलिखित समकक्ष करेगा:

test = string_replace( string_replace( test, "abc", "hij"), "def", "klm")

3

रोटमैक्स के उत्तर पर सामान्यीकरण, एक स्ट्रिंग में सभी उदाहरणों को खोजने और बदलने के लिए यहां एक पूर्ण समाधान है। यदि दोनों संक्षारण अलग-अलग आकार के हैं, तो स्ट्रिंग स्ट्रिंग: इरेज़ और स्ट्रिंग :: इंसर्ट का उपयोग करके प्रतिस्थापित कर दिया जाता है, अन्यथा तेज़ स्ट्रिंग :: प्रतिस्थापित का उपयोग किया जाता है।

void FindReplace(string& line, string& oldString, string& newString) {
  const size_t oldSize = oldString.length();

  // do nothing if line is shorter than the string to find
  if( oldSize > line.length() ) return;

  const size_t newSize = newString.length();
  for( size_t pos = 0; ; pos += newSize ) {
    // Locate the substring to replace
    pos = line.find( oldString, pos );
    if( pos == string::npos ) return;
    if( oldSize == newSize ) {
      // if they're same size, use std::string::replace
      line.replace( pos, oldSize, newString );
    } else {
      // if not same size, replace by erasing and inserting
      line.erase( pos, oldSize );
      line.insert( pos, newString );
    }
  }
}

2

आपको लगता है कि आवश्यक सबस्ट्रिंग स्ट्रिंग में मौजूद है यकीन कर रहे हैं, तो यह की पहली घटना का स्थान ले लेगा "abc"को"hij"

test.replace( test.find("abc"), 3, "hij");

यदि आप परीक्षण में "एबीसी" नहीं है तो यह दुर्घटनाग्रस्त हो जाएगा, इसलिए इसका उपयोग सावधानी से करें।


1

यहाँ एक समाधान है जो मैंने बिल्डर रणनीति का उपयोग करके लिखा है:

#include <string>
#include <sstream>

using std::string;
using std::stringstream;

string stringReplace (const string& source,
                      const string& toReplace,
                      const string& replaceWith)
{
  size_t pos = 0;
  size_t cursor = 0;
  int repLen = toReplace.length();
  stringstream builder;

  do
  {
    pos = source.find(toReplace, cursor);

    if (string::npos != pos)
    {
        //copy up to the match, then append the replacement
        builder << source.substr(cursor, pos - cursor);
        builder << replaceWith;

        // skip past the match 
        cursor = pos + repLen;
    }
  } 
  while (string::npos != pos);

  //copy the remainder
  builder << source.substr(cursor);

  return (builder.str());
}

टेस्ट:

void addTestResult (const string&& testId, bool pass)
{
  ...
}

void testStringReplace()
{
    string source = "123456789012345678901234567890";
    string toReplace = "567";
    string replaceWith = "abcd";
    string result = stringReplace (source, toReplace, replaceWith);
    string expected = "1234abcd8901234abcd8901234abcd890";

    bool pass = (0 == result.compare(expected));
    addTestResult("567", pass);


    source = "123456789012345678901234567890";
    toReplace = "123";
    replaceWith = "-";
    result = stringReplace(source, toReplace, replaceWith);
    expected = "-4567890-4567890-4567890";

    pass = (0 == result.compare(expected));
    addTestResult("start", pass);


    source = "123456789012345678901234567890";
    toReplace = "0";
    replaceWith = "";
    result = stringReplace(source, toReplace, replaceWith);
    expected = "123456789123456789123456789"; 

    pass = (0 == result.compare(expected));
    addTestResult("end", pass);


    source = "123123456789012345678901234567890";
    toReplace = "123";
    replaceWith = "-";
    result = stringReplace(source, toReplace, replaceWith);
    expected = "--4567890-4567890-4567890";

    pass = (0 == result.compare(expected));
    addTestResult("concat", pass);


    source = "1232323323123456789012345678901234567890";
    toReplace = "323";
    replaceWith = "-";
    result = stringReplace(source, toReplace, replaceWith);
    expected = "12-23-123456789012345678901234567890";

    pass = (0 == result.compare(expected));
    addTestResult("interleaved", pass);



    source = "1232323323123456789012345678901234567890";
    toReplace = "===";
    replaceWith = "-";
    result = utils_stringReplace(source, toReplace, replaceWith);
    expected = source;

    pass = (0 == result.compare(expected));
    addTestResult("no match", pass);

}

0
    string & replace(string & subj, string old, string neu)
    {
        size_t uiui = subj.find(old);
        if (uiui != string::npos)
        {
           subj.erase(uiui, old.size());
           subj.insert(uiui, neu);
        }
        return subj;
    }

मुझे लगता है कि यह कुछ कोड के साथ आपकी आवश्यकता फिट बैठता है!


आप कई घटनाओं / प्रतिस्थापनों को ध्यान में नहीं
रख रहे हैं

0

@Czarek Tomczak द्वारा इम्प्रेस किया गया संस्करण।
दोनों की अनुमति दें std::stringऔर std::wstring

template <typename charType>
void ReplaceSubstring(std::basic_string<charType>& subject,
    const std::basic_string<charType>& search,
    const std::basic_string<charType>& replace)
{
    if (search.empty()) { return; }
    typename std::basic_string<charType>::size_type pos = 0;
    while((pos = subject.find(search, pos)) != std::basic_string<charType>::npos) {
         subject.replace(pos, search.length(), replace);
         pos += replace.length();
    }
}

0
std::string replace(const std::string & in
                  , const std::string & from
                  , const std::string & to){
  if(from.size() == 0 ) return in;
  std::string out = "";
  std::string tmp = "";
  for(int i = 0, ii = -1; i < in.size(); ++i) {
    // change ii
    if     ( ii <  0 &&  from[0] == in[i] )  {
      ii  = 0;
      tmp = from[0]; 
    } else if( ii >= 0 && ii < from.size()-1 )  {
      ii ++ ;
      tmp = tmp + in[i];
      if(from[ii] == in[i]) {
      } else {
        out = out + tmp;
        tmp = "";
        ii = -1;
      }
    } else {
      out = out + in[i];
    }
    if( tmp == from ) {
      out = out + to;
      tmp = "";
      ii = -1;
    }
  }
  return out;
};

0

यहां एक समाधान है जो पुनरावर्तन का उपयोग करता है जो एक प्रतिस्थापन के सभी घटनाओं को दूसरे प्रतिस्थापन के साथ बदल देता है। यह स्ट्रिंग्स के आकार से कोई फर्क नहीं पड़ता।

std::string ReplaceString(const std::string source_string, const std::string old_substring, const std::string new_substring)
{
    // Can't replace nothing.
    if (old_substring.empty())
        return source_string;

    // Find the first occurrence of the substring we want to replace.
    size_t substring_position = source_string.find(old_substring);

    // If not found, there is nothing to replace.
    if (substring_position == std::string::npos)
        return source_string;

    // Return the part of the source string until the first occurance of the old substring + the new replacement substring + the result of the same function on the remainder.
    return source_string.substr(0,substring_position) + new_substring + ReplaceString(source_string.substr(substring_position + old_substring.length(),source_string.length() - (substring_position + old_substring.length())), old_substring, new_substring);
}

उपयोग उदाहरण:

std::string my_cpp_string = "This string is unmodified. You heard me right, it's unmodified.";
std::cout << "The original C++ string is:\n" << my_cpp_string << std::endl;
my_cpp_string = ReplaceString(my_cpp_string, "unmodified", "modified");
std::cout << "The final C++ string is:\n" << my_cpp_string << std::endl;

0
std::string replace(std::string str, std::string substr1, std::string substr2)
{
    for (size_t index = str.find(substr1, 0); index != std::string::npos && substr1.length(); index = str.find(substr1, index + substr2.length() ) )
        str.replace(index, substr1.length(), substr2);
    return str;
}

लघु समाधान जहां आपको किसी अतिरिक्त पुस्तकालय की आवश्यकता नहीं है।


इस सवाल के 14 अन्य उत्तर हैं। क्यों नहीं एक स्पष्टीकरण के रूप में क्यों तुम्हारा कोई बेहतर है?
chb

0
std::string replace(std::string str, const std::string& sub1, const std::string& sub2)
{
    if (sub1.empty())
        return str;

    std::size_t pos;
    while ((pos = str.find(sub1)) != std::string::npos)
        str.replace(pos, sub1.size(), sub2);

    return str;
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.