স্ট্রিংয়ের অংশটিকে অন্য স্ট্রিংয়ের সাথে প্রতিস্থাপন করা কি সি ++ তে সম্ভব?
মূলত, আমি এটি করতে চাই:
QString string("hello $name");
string.replace("$name", "Somename");
তবে আমি স্ট্যান্ডার্ড সি ++ লাইব্রেরি ব্যবহার করতে চাই।
স্ট্রিংয়ের অংশটিকে অন্য স্ট্রিংয়ের সাথে প্রতিস্থাপন করা কি সি ++ তে সম্ভব?
মূলত, আমি এটি করতে চাই:
QString string("hello $name");
string.replace("$name", "Somename");
তবে আমি স্ট্যান্ডার্ড সি ++ লাইব্রেরি ব্যবহার করতে চাই।
উত্তর:
স্ট্রিং ( find
) এর মধ্যে একটি স্ট্রিংয়ের সন্ধান করার জন্য একটি ফাংশন রয়েছে এবং একটি স্ট্রিংয়ে একটি নির্দিষ্ট রেঞ্জকে অন্য স্ট্রিং ( replace
) দিয়ে প্রতিস্থাপন করার জন্য একটি ফাংশন রয়েছে , যাতে আপনি এগুলি আপনার পছন্দসই প্রভাবটি পেতে একত্রিত করতে পারেন:
bool replace(std::string& str, const std::string& from, const std::string& to) {
size_t start_pos = str.find(from);
if(start_pos == std::string::npos)
return false;
str.replace(start_pos, from.length(), to);
return true;
}
std::string string("hello $name");
replace(string, "$name", "Somename");
একটি মন্তব্যের জবাবে, আমি মনে করি replaceAll
সম্ভবত এটির মতো দেখতে লাগবে:
void replaceAll(std::string& str, const std::string& from, const std::string& to) {
if(from.empty())
return;
size_t start_pos = 0;
while((start_pos = str.find(from, start_pos)) != std::string::npos) {
str.replace(start_pos, from.length(), to);
start_pos += to.length(); // In case 'to' contains 'from', like replacing 'x' with 'yx'
}
}
from
এবং to
পাস করা হয় না const
? যদি from
না থাকে তবে আপনার কাজটি কী করবে ? -1
আমার জন্য।
const
এবং যদি আমি এর মতো কোনও ইউটিলিটি পদ্ধতি লিখি তবে আমি কেবল এটিই জানতাম যদি আমি জানতাম প্রতিস্থাপন বৈধ ছিল
const
করা সি ++ 'সেরা সরঞ্জামগুলির মধ্যে একটিকে উপেক্ষা করছে। ফাংশন পরামিতিগুলির জন্য রেফারেন্স প্রতি পাসিং const
ডিফল্ট মোড হওয়া উচিত। (এফটিআর, ছাড়াই const
আপনি এমনকি আপনার ফাংশনে স্ট্রিং লিটারেলও দিতে পারেননি, কারণ আপনি অ- const
রেফারেন্সগুলিতে টেম্পোরারিগুলিকে আবদ্ধ করতে পারবেন না the সুতরাং ফাংশন এমনকি এটিতে যা লেখা হয়েছিল তাও করতে পারে না))
সি ++ এর মাধ্যমে আপনি এর std::regex
মতো ব্যবহার করতে পারেন :
#include <regex>
...
std::string string("hello $name");
string = std::regex_replace(string, std::regex("\\$name"), "Somename");
পালানোর চরিত্রটি পালনের জন্য ডাবল ব্যাকস্ল্যাশ প্রয়োজন।
std::regex_replace
যে Qt এর স্ট্রিং গ্রহণ করে না pretty
string
মাধ্যমে সংশোধন করা যেতে পারে string.toStdString()
।
String
হয়ে std::string
, কারণ প্রশ্নটি Qt সম্পর্কিত নয়। দয়া করে এটি করা বিবেচনা করুন - আমি পরে আপনার উত্তরটি সানন্দে উপস্থাপন করব।
R"(\$name)"
পরিবর্তে লিখতে দেয় "\\$name"
।
std::string
একটি replace
পদ্ধতি আছে, আপনি কি এটি খুঁজছেন?
আপনি চেষ্টা করতে পারেন:
s.replace(s.find("$name"), sizeof("$name") - 1, "Somename");
আমি নিজেকে চেষ্টা করিনি, শুধু উপর ডকুমেন্টেশন পড়া find()
এবংreplace()
।
নতুন স্ট্রিংটি ফিরে পেতে এটি ব্যবহার করুন:
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 modified: "
<< 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
হ্যাঁ, আপনি এটি করতে পারেন, তবে আপনাকে স্ট্রিংয়ের সন্ধান () সদস্যের সাথে প্রথম স্ট্রিংয়ের অবস্থানটি অনুসন্ধান করতে হবে এবং তারপরে এটি প্রতিস্থাপন () সদস্যের সাথে প্রতিস্থাপন করতে হবে।
string s("hello $name");
size_type pos = s.find( "$name" );
if ( pos != string::npos ) {
s.replace( pos, 5, "somename" ); // 5 = length( $name )
}
আপনি যদি স্ট্যান্ডার্ড লাইব্রেরিটি ব্যবহার করার পরিকল্পনা করে থাকেন তবে আপনার সত্যিকারের সি ++ স্ট্যান্ডার্ড লাইব্রেরি বইটির একটি অনুলিপি পাওয়া উচিত যা এই সমস্ত জিনিস খুব ভালভাবে কভার করে।
আমি সাধারণত এটি ব্যবহার করি:
std::string& replace(std::string& s, const std::string& from, const std::string& to)
{
if(!from.empty())
for(size_t pos = 0; (pos = s.find(from, pos)) != std::string::npos; pos += to.size())
s.replace(pos, from.size(), to);
return s;
}
কিছু বার না পাওয়া std::string::find()
পর্যন্ত এটি বার বার অনুসন্ধানের স্ট্রিংয়ের অন্যান্য উপস্থিতিগুলি সনাক্ত করতে কল std::string::find()
করে। কারণ ম্যাচের অবস্থানটিstd::string::find()
ফিরিয়ে দেয় আমাদের অকার্যকরদের অবৈধ করার সমস্যা নেই।
এটি একটি বিকল্প মত শোনাচ্ছে
string.replace(string.find("%s"), string("%s").size(), "Something");
আপনি এটি কোনও ফাংশনে মুড়িয়ে রাখতে পারেন তবে এই এক-লাইন সমাধানটি গ্রহণযোগ্য মনে হচ্ছে। সমস্যাটি হ'ল এটি কেবল প্রথম ঘটনাটি পরিবর্তিত করবে, আপনি এটির উপর লুপ করতে চাইতে পারেন তবে এটি আপনাকে একই টোকেনের সাহায্যে এই স্ট্রিংয়ে বেশ কয়েকটি ভেরিয়েবল সন্নিবেশ করতে দেয় %s
)
str.replace(str.find("%s"), string("%s").size(), "Something");
সমস্ত স্ট্রিং যদি স্ট্যান্ড :: স্ট্রিং হয় তবে আপনি অক্ষরগুলির কাট অফের সাথে অদ্ভুত সমস্যাগুলি ব্যবহার করতে পারেন sizeof()
কারণ এটি সি স্ট্রিংগুলির জন্য বোঝানো হয়েছে, সি ++ স্ট্রিং নয়। ফিক্সটি হল .size()
ক্লাসের পদ্ধতিটি ব্যবহার করা std::string
।
sHaystack.replace(sHaystack.find(sNeedle), sNeedle.size(), sReplace);
এটি হাইস্ট্যাক ইনলাইন প্রতিস্থাপন করে - এটির জন্য একটি = এসাইনমেন্ট করার দরকার নেই।
ব্যবহারের উদাহরণ:
std::string sHaystack = "This is %XXX% test.";
std::string sNeedle = "%XXX%";
std::string sReplace = "my special";
sHaystack.replace(sHaystack.find(sNeedle),sNeedle.size(),sReplace);
std::cout << sHaystack << std::endl;
wstring myString = L"Hello $$ this is an example. By $$.";
wstring search = L"$$";
wstring replace = L"Tom";
for (int i = myString.find(search); i >= 0; i = myString.find(search))
myString.replace(i, search.size(), replace);
আপনি যদি এটি দ্রুত করতে চান তবে আপনি দুটি স্ক্যান পদ্ধতির ব্যবহার করতে পারেন। সুডোকোড:
আমি নিশ্চিত না যে এটি কোনও স্থানের পূর্ববর্তী স্থানে অনুকূলিত করা যায় কিনা।
এবং একটি সি ++ 11 কোড উদাহরণ কিন্তু আমি কেবল একটি চরের জন্য অনুসন্ধান করি।
#include <string>
#include <iostream>
#include <algorithm>
using namespace std;
void ReplaceString(string& subject, char search, const string& replace)
{
size_t initSize = subject.size();
int count = 0;
for (auto c : subject) {
if (c == search) ++count;
}
size_t idx = subject.size()-1 + count * replace.size()-1;
subject.resize(idx + 1, '\0');
string reverseReplace{ replace };
reverse(reverseReplace.begin(), reverseReplace.end());
char *end_ptr = &subject[initSize - 1];
while (end_ptr >= &subject[0])
{
if (*end_ptr == search) {
for (auto c : reverseReplace) {
subject[idx - 1] = c;
--idx;
}
}
else {
subject[idx - 1] = *end_ptr;
--idx;
}
--end_ptr;
}
}
int main()
{
string s{ "Mr John Smith" };
ReplaceString(s, ' ', "%20");
cout << s << "\n";
}
std::string replace(std::string base, const std::string from, const std::string to) {
std::string SecureCopy = base;
for (size_t start_pos = SecureCopy.find(from); start_pos != std::string::npos; start_pos = SecureCopy.find(from,start_pos))
{
SecureCopy.replace(start_pos, from.length(), to);
}
return SecureCopy;
}
আমার নিজের প্রয়োগটি, অ্যাকাউন্টটি গ্রহণ করে স্ট্রিংটিকে কেবল একবার পুনরায় আকার দেওয়া দরকার, তারপরে প্রতিস্থাপন ঘটতে পারে।
template <typename T>
std::basic_string<T> replaceAll(const std::basic_string<T>& s, const T* from, const T* to)
{
auto length = std::char_traits<T>::length;
size_t toLen = length(to), fromLen = length(from), delta = toLen - fromLen;
bool pass = false;
std::string ns = s;
size_t newLen = ns.length();
for (bool estimate : { true, false })
{
size_t pos = 0;
for (; (pos = ns.find(from, pos)) != std::string::npos; pos++)
{
if (estimate)
{
newLen += delta;
pos += fromLen;
}
else
{
ns.replace(pos, fromLen, to);
pos += delta;
}
}
if (estimate)
ns.resize(newLen);
}
return ns;
}
ব্যবহার উদাহরণস্বরূপ হতে পারে:
std::string dirSuite = replaceAll(replaceAll(relPath.parent_path().u8string(), "\\", "/"), ":", "");
আমি এখনই সি ++ শিখছি, তবে পূর্বে পোস্ট করা কিছু কোড সম্পাদনা করছি, আমি সম্ভবত এরকম কিছু ব্যবহার করব। এটি আপনাকে 1 বা একাধিক দৃষ্টান্ত প্রতিস্থাপনের জন্য নমনীয়তা দেয় এবং শুরু বিন্দুটি নির্দিষ্ট করতে দেয়।
using namespace std;
// returns number of replacements made in string
long strReplace(string& str, const string& from, const string& to, size_t start = 0, long count = -1) {
if (from.empty()) return 0;
size_t startpos = str.find(from, start);
long replaceCount = 0;
while (startpos != string::npos){
str.replace(startpos, from.length(), to);
startpos += to.length();
replaceCount++;
if (count > 0 && replaceCount >= count) break;
startpos = str.find(from, startpos);
}
return replaceCount;
}
এটি ব্যবহার করা আরও ভাল হতে পারে
void replace(string& input, const string& from, const string& to)
{
while(true)
{
size_t startPosition = input.find(from);
if(startPosition == string::npos)
break;
input.replace(startPosition, from.length(), to);
}
}