আরেকটি স্ট্রিং সি ++ দিয়ে সাবস্ট্রিং প্রতিস্থাপন করুন


91

আমি কীভাবে স্ট্রিংয়ের একটি স্ট্রিংগুলিকে সি ++ তে অন্য সাবস্ট্রিংয়ের সাথে প্রতিস্থাপন করতে পারি, আমি কোন ফাংশন ব্যবহার করতে পারি?

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

4
স্ট্যাকওভারফ্লো / প্রশ্নগুলি / 3418231 /… এর খুব বেশি একটি সদৃশ যা এর স্বীকৃত উত্তরে আরও দৃ solution সমাধান রয়েছে।
ডেভ-হলম

উত্তর:


77

এটি করার জন্য সি ++ তে কোনও অন্তর্নির্মিত ফাংশন নেই। আপনি যদি একটি স্ট্রিংয়ের সমস্ত দৃষ্টান্ত অন্যটির সাথে প্রতিস্থাপন করতে চান তবে আপনি কল 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 স্ট্রিংয়ের length স্ট্রিংয়ের দৈর্ঘ্য দ্বারা । প্রতিস্থাপন - এই বিশেষ উদাহরণে "abc"সঙ্গে "def"- এই আসলে প্রয়োজন নেই। তবে আরও সাধারণ সেটিংয়ে সবেমাত্র প্রতিস্থাপন করা স্ট্রিংটি বাদ দেওয়া গুরুত্বপূর্ণ। উদাহরণস্বরূপ, যদি আপনি প্রতিস্থাপন করতে চান "abc"সঙ্গে "abcabc"নতুন প্রতিস্থাপিত স্ট্রিং সেগমেন্ট উপর কুঁদন ছাড়া, এই কোড ক্রমাগত নতুন প্রতিস্থাপিত স্ট্রিং অংশ প্রতিস্থাপন পর্যন্ত মেমরির ক্লান্ত করছে। স্বতন্ত্রভাবে, যাইহোক যাইহোক এই নতুন অক্ষরগুলি এড়িয়ে যাওয়া কিছুটা দ্রুত হতে পারে, কারণ এটি করার ফলে string::findফাংশনের ফলে কিছু সময় এবং প্রচেষ্টা সাশ্রয় হয়।

আশাকরি এটা সাহায্য করবে!


6
আমি বিশ্বাস করি না যে আপনাকে ইনক্রিমেন্ট ইনডেক্সের প্রয়োজন হবে কারণ আপনি ইতিমধ্যে ডেটা প্রতিস্থাপন করেছেন যাতে এটি কোনওভাবেই এটি গ্রহণ না করে।
rossb83

4
@ এডিয়াকাপি যদি এটি কোনও সাধারণ উদ্দেশ্য ফাংশনে রূপান্তরিত হয় তবে এটি কোনও অসীম লুপে আটকে যাবে না কারণ এটি indexপ্রতিস্থাপন করা স্ট্রিংয়ের অংশটি অনুসন্ধানের অবস্থানকে ( ) অগ্রসর করে adv
টিম আর

4
@ টিমআর। আপনি ঠিক বলেছেন, আমি রসব ৩৮-এর প্রতিক্রিয়া জানিয়েছিলাম যিনি বলেছেন যে সূচকের বৃদ্ধি অপ্রয়োজনীয়। কেবল ভুল তথ্য রোধ করার চেষ্টা করছিল। অন্য সবার জন্য: প্রতিস্থাপিত স্ট্রিংয়ের দৈর্ঘ্য অনুসারে সূচক বাড়ানো (এই ক্ষেত্রে 3) প্রয়োজনীয় । কোড নমুনা থেকে এটি অপসারণ করবেন না।
এডিয়াকাপি

@ ফ্রোজেনকিউই শুনে আমি অবাক হই। আপনি কি নিশ্চিত যে ঘটনাটি?
টেমপ্লেটিপটিফ

4
@ জুলিয়ানসিএনফুয়েগোস আমি ঠিক এই উত্তরটির উত্তর আপডেট করেছি - এটি নির্দেশ করার জন্য ধন্যবাদ! (এছাড়াও, 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
জে। সমস্ত সাবস্ট্রিংগুলি প্রতিস্থাপনের জন্য আমার বুস্ট দরকার।
জোহানেস ওভারম্যান

4
বুস্ট বেশিরভাগই একটি ওভারকিল।
কনরাড

63

ভিতরে , আপনি ব্যবহার করতে পারেন std::regex_replace:

#include <string>
#include <regex>

std::string test = "abc def abc def";
test = std::regex_replace(test, std::regex("def"), "klm");

4
আমাদের সি ++ 11 থাকলে এটি দুর্দান্ত হবে!
মিশেল

4
# অন্তর্ভুক্ত <রিজেেক্স>
স্টেপান ইয়াকোভেনকো

43

আমি মনে করি যদি প্রতিস্থাপনের স্ট্রিংয়ের দৈর্ঘ্য প্রতিস্থাপনের স্ট্রিংয়ের দৈর্ঘ্যের চেয়ে পৃথক হয় তবে সমস্ত সমাধান ব্যর্থ হবে। ("এবিসি" সন্ধান করুন এবং "এক্সএক্সএক্সএক্সএক্সএক্সএক্সএক্সএক্সএক্সএক্সএক্সএক্স") একটি সাধারণ পদ্ধতির হতে পারে:

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 প্রতিস্থাপন সাবস্ট্রিং হয়

4
এটি কেবল প্রথম ঘটনাটি প্রতিস্থাপন করে, তাই না?
jpo38

4
আমি str.find (str2) এর ফলাফলটি std :: স্ট্রিংয়ের সমান হয় না তা নিশ্চিত করার পরামর্শ দিচ্ছি: npos অটো পাওয়া গেছে = str.find (str2); if (পাওয়া! = স্টেডি :: স্ট্রিং :: এনপোস)
জিওফ লেন্টস

4
আমি এটির সাথে পুরো অ্যাপ্লিকেশনটি লেখার ইচ্ছা করছিলাম না, তবে ইনপুটটিতে কোনও চেক না করেই এর কিছু সংজ্ঞা দেওয়া নেই ....
জেফ জ্যাচার

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.leth (), str3); শুধু সহজ এবং ভাল কাজ করে।
কমিকেজ

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

আপনি যে প্রয়োজনীয় সাবস্ট্রিং স্ট্রিং উপস্থিত নিশ্চিত হন তাহলে, তারপর, এই প্রথম occurence প্রতিস্থাপন করবে "abc"করার"hij"

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

যদি আপনি পরীক্ষায় "abc" না পান তবে এটি ক্রাশ হবে, সুতরাং এটি যত্ন সহ ব্যবহার করুন।


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

@ কেজারেক টমকজাক দ্বারা প্ররোচিত সংস্করণ।
উভয় 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

এখানে পুনরাবৃত্তির সাহায্যে একটি সমাধান রয়েছে যা একটি স্ট্রিংয়ের সমস্ত উপস্থিতিকে অন্য একটি স্ট্রিংয়ের সাথে প্রতিস্থাপন করে। এটি স্ট্রিংয়ের আকারের কোনও বিষয় নয় works

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

সংক্ষিপ্ত সমাধান যেখানে আপনার কোনও অতিরিক্ত গ্রন্থাগার প্রয়োজন নেই।


4
এই প্রশ্নের আরও 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;
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.