Apakah ada cara untuk mengganti semua kemunculan substring dengan string lain di std::string
?
Misalnya:
void SomeFunction(std::string& str)
{
str = str.replace("hello", "world"); //< I'm looking for something nice like this
}
Apakah ada cara untuk mengganti semua kemunculan substring dengan string lain di std::string
?
Misalnya:
void SomeFunction(std::string& str)
{
str = str.replace("hello", "world"); //< I'm looking for something nice like this
}
Jawaban:
Mengapa tidak menerapkan penggantian Anda sendiri?
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();
}
}
#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");
Berikut adalah dokumentasi resmi di replace_all.
replace_all
akan segfault untuk versi peningkatan> 1.43 di Sun Studio untuk versi apa pun <12.3
boost
meningkatkan waktu kompilasi secara signifikan pada perangkat yang disematkan. Bahkan quad core ARMv7. 100 baris kode dikompilasi dalam 2 menit, tanpa peningkatan, 2 detik.
Di C ++ 11, Anda dapat melakukan ini sebagai satu baris dengan panggilan ke 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;
keluaran:
Removeallspaces
from
bisa menjadi ekspresi reguler - sehingga Anda bisa menggunakan kriteria pencocokan yang lebih canggih jika perlu. Apa yang tidak saya lihat adalah bagaimana melakukan ini tanpa menerapkan beberapa bentuk penguraian ekspresi reguler - alih-alih hanya menggunakan interpretasi langsung dari from
karakter.
Mengapa tidak mengembalikan string yang dimodifikasi?
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;
}
Jika Anda membutuhkan kinerja, berikut adalah fungsi yang dioptimalkan yang mengubah string input, itu tidak membuat salinan dari string:
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();
}
}
Tes:
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;
Keluaran:
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
Temukan-dan-ganti sebaris saya di tempat:
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;
}
Ini mengembalikan hitungan jumlah item yang diganti (untuk digunakan jika Anda ingin menjalankan ini secara berturut-turut, dll). Untuk menggunakannya:
std::string str = "one two three";
int n = findAndReplace(str, "one", "1");
Cara termudah (menawarkan sesuatu yang mendekati apa yang Anda tulis) adalah dengan menggunakan Boost.Regex , khususnya regex_replace .
std :: string telah membangun metode find () dan replace (), tetapi metode ini lebih rumit untuk digunakan karena mereka memerlukan penanganan indeks dan panjang string.
Saya yakin ini akan berhasil. Dibutuhkan const char * sebagai parameter.
//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;
}
}
size_type
untuk string adalah unsigned
, >=
pemeriksaan Anda dalam kondisi loop akan selalu true
. Anda harus menggunakannya di std::string::npos
sana.
roll_down_window
// 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;
}
#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();
}
}
Pemeriksaan untuk oldStr kosong itu penting. Jika karena alasan apa pun parameter itu kosong, Anda akan terjebak dalam loop tak terbatas.
Tapi ya gunakan solusi C ++ 11 atau Boost yang telah dicoba dan diuji jika Anda bisa.