@poly Saya akan berpikir ini pasti telah diminta untuk C ++ juga, tapi saya tidak dapat menemukannya
Michael Mrozek
1
Ada tag std pada pertanyaan, tetapi mungkin Anda mungkin tertarik pada algoritma string boost, yang juga mencakup berbagai pilihan algoritma ganti (inplace / copy, case-sensitive / case-sensitive, ganti first / last / all / n-th) ).
Ada fungsi untuk menemukan substring dalam string ( find), dan fungsi untuk mengganti rentang tertentu dalam string dengan string lain ( replace), sehingga Anda bisa menggabungkan mereka untuk mendapatkan efek yang Anda inginkan:
Bagaimana saya memperbaikinya jika string asli memiliki lebih dari satu contoh "$ name" dan saya ingin mengganti semuanya.
Tom Leese
1
Mengapa tidak fromdan tolulus per constreferensi? Apa fungsi Anda jika fromtidak ada? -1dari saya untuk itu.
sbi
10
@ sbi Memperbaiki, walaupun Anda bisa mengartikannya sebagai rekomendasi alih-alih serangan - itu tidak terpikir oleh saya, saya jarang berpikir untuk menggunakan constdan jika saya menulis metode utilitas seperti ini saya hanya akan menyebutnya jika saya tahu penggantian itu valid
Michael Mrozek
10
@Michael: Bagus, saya mengubah suara saya menjadi suara-up. Mengabaikan constmengabaikan salah satu alat terbaik C ++. Lulus per constreferensi harus menjadi mode default untuk parameter fungsi. (FTR, tanpa const, Anda bahkan tidak bisa meneruskan string literal ke fungsi Anda, karena Anda tidak dapat mengikat sementara ke non- constreferensi. Jadi fungsi tersebut bahkan tidak akan melakukan apa yang ditulis untuk.)
sbi
19
Apakah ini masih satu-satunya solusi di tahun 2018? Jika demikian dan setiap komite C ++ sedang membaca ini, aturlah. Ini memalukan. split (string, string) dan ganti (string, string) tolong!
user997112
96
Dengan C ++ 11 Anda dapat menggunakan std::regexseperti ini:
Saya cukup yakin std::regex_replacetidak menerima string Qt.
BartoszKP
1
Kamu benar. Ketika itu terjadi, QString menyediakan metode pengganti yang menerima QRexExp, memungkinkan untuk menggunakan barang-barang Qt sendiri. Tapi saya pikir jawaban saat ini bisa diperbaiki dengan mengganti stringdengan string.toStdString().
Tom
1
Atau hanya dengan mengubah Stringke std::string, karena pertanyaannya tidak terkait dengan Qt. Silakan pertimbangkan untuk melakukan itu - Saya dengan senang hati akan meningkatkan jawaban Anda setelahnya.
BartoszKP
5
String mentah memungkinkan untuk menulis R"(\$name)"bukan "\\$name".
Jarod42
2
Berapa ini akan lebih lambat daripada menemukan / mengganti tanpa mempertimbangkan waktu membangun std :: regex?
jw_
18
std::string mempunyai sebuah replace metode, apakah itu yang Anda cari?
Panggilan Anda ke subject.replace di ReplaceStringInPlace () apakah itu benar-benar memodifikasi string di tempat?
Damian
Saya melihat sumbernya sebentar dan sepertinya menggunakan semantik untuk memindahkan bagian depan string lama ke tempatnya, sehingga tidak disalin, tetapi bagian yang baru dimasukkan akan disalin ke string yang lama dan ekor dari string yang lama. disalin ke dalam buffered dari string lama. Ada kemungkinan bahwa string melebar begitu banyak seluruh buffer yang mendasarinya dialokasikan kembali, tetapi jika Anda mengganti 1 ke 1 seperti dalam contohnya, saya pikir itu terjadi "di tempat", atau tanpa menyalin, tetapi jika Anda memperluas string, hanya bagian pertama dari string lama yang tidak disalin, dan hanya mungkin kemudian.
Motes
6
Ya, Anda dapat melakukannya, tetapi Anda harus menemukan posisi string pertama dengan anggota find (), dan kemudian ganti dengan anggota replace ().
Jika Anda berencana menggunakan Perpustakaan Standar, Anda harus benar-benar mendapatkan salinan buku Perpustakaan C ++ Standar yang mencakup semua hal ini dengan sangat baik.
Berulang kali panggilan std::string::find()untuk mencari kejadian lain dari string yang dicari sampai std::string::find()tidak menemukan apa pun. Karena std::string::find()mengembalikan posisi pertandingan, kami tidak memiliki masalah untuk membatalkan iterator.
Anda bisa membungkus ini dalam suatu fungsi tetapi solusi satu baris ini terdengar dapat diterima. Masalahnya adalah ini akan mengubah kejadian pertama saja, Anda mungkin ingin mengulanginya, tetapi juga memungkinkan Anda untuk memasukkan beberapa variabel ke string ini dengan token yang sama ( %s)
Menyukai gaya tetapi menemukan string yang berbeda membingungkan ^^str.replace(str.find("%s"), string("%s").size(), "Something");
Paul Würtz
3
Jika semua string std :: string, Anda akan menemukan masalah aneh dengan cutoff karakter jika menggunakan sizeof()karena itu dimaksudkan untuk string C, bukan string C ++. Cara mengatasinya adalah dengan menggunakan .size()metode kelas std::string.
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);
Saya baru saja belajar C ++, tetapi mengedit beberapa kode yang sebelumnya diposting, saya mungkin akan menggunakan sesuatu seperti ini. Ini memberi Anda fleksibilitas untuk mengganti 1 atau beberapa instance, dan juga memungkinkan Anda menentukan titik awal.
Jawaban:
Ada fungsi untuk menemukan substring dalam string (
find
), dan fungsi untuk mengganti rentang tertentu dalam string dengan string lain (replace
), sehingga Anda bisa menggabungkan mereka untuk mendapatkan efek yang Anda inginkan:Menanggapi komentar, saya pikir
replaceAll
mungkin akan terlihat seperti ini:sumber
from
danto
lulus perconst
referensi? Apa fungsi Anda jikafrom
tidak ada?-1
dari saya untuk itu.const
dan jika saya menulis metode utilitas seperti ini saya hanya akan menyebutnya jika saya tahu penggantian itu validconst
mengabaikan salah satu alat terbaik C ++. Lulus perconst
referensi harus menjadi mode default untuk parameter fungsi. (FTR, tanpaconst
, Anda bahkan tidak bisa meneruskan string literal ke fungsi Anda, karena Anda tidak dapat mengikat sementara ke non-const
referensi. Jadi fungsi tersebut bahkan tidak akan melakukan apa yang ditulis untuk.)Dengan C ++ 11 Anda dapat menggunakan
std::regex
seperti ini:Double backslash diperlukan untuk melarikan diri dari karakter pelarian.
sumber
std::regex_replace
tidak menerima string Qt.string
denganstring.toStdString()
.String
kestd::string
, karena pertanyaannya tidak terkait dengan Qt. Silakan pertimbangkan untuk melakukan itu - Saya dengan senang hati akan meningkatkan jawaban Anda setelahnya.R"(\$name)"
bukan"\\$name"
.std::string
mempunyai sebuahreplace
metode, apakah itu yang Anda cari?Kamu bisa mencoba:
Saya belum mencoba sendiri, cukup baca dokumentasi
find()
danreplace()
.sumber
Untuk mengembalikan string baru, gunakan ini:
Jika Anda membutuhkan kinerja, berikut ini adalah fungsi yang dioptimalkan yang memodifikasi string input, ini tidak membuat salinan string:
Tes:
Keluaran:
sumber
Ya, Anda dapat melakukannya, tetapi Anda harus menemukan posisi string pertama dengan anggota find (), dan kemudian ganti dengan anggota replace ().
Jika Anda berencana menggunakan Perpustakaan Standar, Anda harus benar-benar mendapatkan salinan buku Perpustakaan C ++ Standar yang mencakup semua hal ini dengan sangat baik.
sumber
Saya menggunakan ini secara umum:
Berulang kali panggilan
std::string::find()
untuk mencari kejadian lain dari string yang dicari sampaistd::string::find()
tidak menemukan apa pun. Karenastd::string::find()
mengembalikan posisi pertandingan, kami tidak memiliki masalah untuk membatalkan iterator.sumber
Ini terdengar seperti opsi
string.replace(string.find("%s"), string("%s").size(), "Something");
Anda bisa membungkus ini dalam suatu fungsi tetapi solusi satu baris ini terdengar dapat diterima. Masalahnya adalah ini akan mengubah kejadian pertama saja, Anda mungkin ingin mengulanginya, tetapi juga memungkinkan Anda untuk memasukkan beberapa variabel ke string ini dengan token yang sama (
%s
)sumber
str.replace(str.find("%s"), string("%s").size(), "Something");
Jika semua string std :: string, Anda akan menemukan masalah aneh dengan cutoff karakter jika menggunakan
sizeof()
karena itu dimaksudkan untuk string C, bukan string C ++. Cara mengatasinya adalah dengan menggunakan.size()
metode kelasstd::string
.Itu menggantikan inline sHaystack - tidak perlu melakukan tugas = kembali itu.
Contoh penggunaan:
sumber
sumber
Jika Anda ingin melakukannya dengan cepat, Anda dapat menggunakan pendekatan dua pemindaian. Kode palsu:
Saya tidak yakin apakah ini dapat dioptimalkan ke algo di tempat.
Dan contoh kode C ++ 11 tapi saya hanya mencari satu karakter.
sumber
sumber
Implementasi saya sendiri, dengan mempertimbangkan bahwa string perlu diubah ukuran hanya sekali, maka ganti bisa terjadi.
Penggunaan bisa misalnya seperti ini:
sumber
Saya baru saja belajar C ++, tetapi mengedit beberapa kode yang sebelumnya diposting, saya mungkin akan menggunakan sesuatu seperti ini. Ini memberi Anda fleksibilitas untuk mengganti 1 atau beberapa instance, dan juga memungkinkan Anda menentukan titik awal.
sumber
Ini bisa lebih baik untuk digunakan
sumber