Bagaimana cara mengganti substring dalam string dengan substring lain di C ++, fungsi apa yang dapat saya gunakan?
eg: string test = "abc def abc def";
test.replace("abc", "hij").replace("def", "klm"); //replace occurrence of abc and def with other substring
Jawaban:
Tidak ada satu pun fungsi bawaan di C ++ untuk melakukan ini. Jika Anda ingin mengganti semua instance dari satu substring dengan yang lain, Anda dapat melakukannya dengan mencampurkan panggilan ke
string::find
danstring::replace
. Sebagai contoh: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; }
Di baris terakhir kode ini, saya telah menambah
index
panjang string yang telah dimasukkan ke dalam string. Dalam contoh khusus ini - mengganti"abc"
dengan"def"
- ini sebenarnya tidak perlu. Namun, dalam pengaturan yang lebih umum, penting untuk melewati string yang baru saja diganti. Misalnya, jika Anda ingin mengganti"abc"
dengan"abcabc"
, tanpa melewatkan segmen string yang baru diganti, kode ini akan terus-menerus mengganti bagian dari string yang baru diganti hingga memori habis. Secara independen, mungkin akan sedikit lebih cepat untuk melewati karakter baru tersebut, karena melakukan hal itu menghemat waktu dan tenaga olehstring::find
fungsinya.Semoga ini membantu!
sumber
index
) melewati bagian dari string yang diganti.Cara Pustaka Algoritme String Tingkatkan :
#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" ); }
sumber
Di c ++ 11, Anda dapat menggunakan
std::regex_replace
:#include <string> #include <regex> std::string test = "abc def abc def"; test = std::regex_replace(test, std::regex("def"), "klm");
sumber
Menurut saya semua solusi akan gagal jika panjang string pengganti berbeda dengan panjang string yang akan diganti. (telusuri "abc" dan ganti dengan "xxxxxx") Pendekatan umum mungkin adalah:
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 ); } }
sumber
Dimana
str
adalah senar dasarstr2
adalah sub string untuk ditemukanstr3
adalah substring penggantisumber
Mengganti substring seharusnya tidak terlalu sulit.
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
sumber
if (search.empty()) { return; }
untuk menghindari loop tak terbatas saat melewati 'pencarian' kosong.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; }
Karena ini bukan anggota
string
kelas, ini tidak mengizinkan sintaks sebaik dalam contoh Anda, tetapi yang berikut ini akan melakukan hal yang setara:test = string_replace( string_replace( test, "abc", "hij"), "def", "klm")
sumber
Menggeneralisasi jawaban rotmax, berikut adalah solusi lengkap untuk mencari & mengganti semua contoh dalam sebuah string. Jika kedua substring memiliki ukuran yang berbeda, substring tersebut diganti menggunakan string :: erase dan string :: insert., Jika tidak, string :: replace yang lebih cepat digunakan.
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 ); } } }
sumber
Jika Anda yakin bahwa substring yang diperlukan ada dalam string, maka ini akan menggantikan kemunculan pertama
"abc"
untuk"hij"
test.replace( test.find("abc"), 3, "hij");
Ini akan macet jika Anda tidak memiliki "abc" dalam pengujian, jadi gunakan dengan hati-hati.
sumber
Berikut adalah solusi yang saya tulis menggunakan taktik pembangun:
#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()); }
Tes:
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); }
sumber
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; }
Saya pikir ini sesuai dengan kebutuhan Anda dengan beberapa kode!
sumber
versi impoved oleh @Czarek Tomczak.
memungkinkan keduanya
std::string
danstd::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(); } }
sumber
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; };
sumber
Berikut adalah solusi menggunakan rekursi yang menggantikan semua kemunculan substring dengan substring lain. Ini berfungsi tidak peduli ukuran senar.
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); }
Contoh penggunaan:
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;
sumber
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; }
Solusi singkat di mana Anda tidak memerlukan Perpustakaan tambahan.
sumber
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; }
sumber