Saya punya string ini:
"Test abc test test abc test test test abc test test abc"
Perbuatan:
str = str.replace('abc', '');
tampaknya hanya menghilangkan kemunculan pertama abc
dalam string di atas.
Bagaimana saya bisa mengganti semua kemunculannya?
javascript
string
replace
Klik Upvote
sumber
sumber
aba
dalamababa
denganca
, yang mengakibatkan yang Anda harapkan?caba
?abca
?cca
?String.prototype.replaceAll()
dikirim di Safari 13.1 dan sekarang di Firefox Nightly dan Chrome Dev dan Canary dan akan dikirim di Firefox 77 dan Chrome 85. Ini belum didokumentasikan dalam MDN, tetapi github.com/tc39/proposal-string-replaceall#high-level-api memiliki explainer: “Jika searchValue adalah string,String.prototype.replaceAll
ganti semua kemunculan searchValue (seolah-olah.split(searchValue).join(replaceValue)
atau ekspresi reguler global & yang diloloskan dengan benar telah digunakan). Jika searchValue adalah ekspresi reguler non-global, berikanString.prototype.replaceAll
pengecualian ”Jawaban:
Catatan: Jangan gunakan ini dalam kode kritis kinerja.
Sebagai alternatif ekspresi reguler untuk string literal sederhana, Anda bisa menggunakannya
Pola umumnya adalah
Ini digunakan dalam beberapa kasus lebih cepat daripada menggunakan
replaceAll
dan ekspresi reguler, tapi itu tampaknya tidak menjadi kasus lagi di browser modern.Benchmark: https://jsperf.com/replace-all-vs-split-join
Kesimpulan: Jika Anda memiliki kasus penggunaan kritis kinerja (misalnya memproses ratusan string), gunakan metode Regexp. Tetapi untuk sebagian besar kasus penggunaan umum, ini layak tidak perlu khawatir tentang karakter khusus.
sumber
String.prototype.replaceAll = function(f,r){return this.split(f).join(r);}
. Penggunaan:"My string".replaceAll('st', '');
menghasilkan "Cincin saya"replaceAll
fungsi yang bagus , dan itu menjadi sama terbaca dengan hal lain. Karena kinerja tidak buruk, tidak ada alasan untuk menghindari solusi ini.Menanggapi komentar:
Sebagai tanggapan terhadap komentar Klik Suara , Anda dapat lebih menyederhanakannya:
Catatan: Ekspresi reguler mengandung karakter khusus (meta), dan karena itu berbahaya untuk secara membabi buta menyampaikan argumen dalam
find
fungsi di atas tanpa pra-pemrosesan untuk menghindari karakter tersebut. Hal ini tercakup dalam Mozilla Developer Jaringan 's JavaScript Panduan pada Regular Expressions , di mana mereka menyajikan fungsi utilitas berikut (yang telah berubah setidaknya dua kali sejak jawaban ini awalnya ditulis, jadi pastikan untuk memeriksa situs MDN untuk update potensial):Jadi untuk membuat
replaceAll()
fungsi di atas lebih aman, itu dapat dimodifikasi menjadi yang berikut jika Anda juga menyertakanescapeRegExp
:sumber
function replaceAll(find, replace,str) { var re = new RegExp(find, 'g'); str = str.replace(re, replace); return str; }
replaceAll
implementasi adalah bahwa itu tidak akan berfungsi jikafind
mengandung karakter meta.Demi kelengkapan, saya harus memikirkan metode apa yang harus saya gunakan untuk melakukan ini. Pada dasarnya ada dua cara untuk melakukan ini seperti yang disarankan oleh jawaban lain di halaman ini.
Catatan: Secara umum, memperluas prototipe bawaan dalam JavaScript umumnya tidak disarankan. Saya menyediakan ekstensi pada prototipe String hanya untuk tujuan ilustrasi, menunjukkan implementasi yang berbeda dari metode standar hipotetis
String
pada prototipe bawaan.Implementasi Berbasis Ekspresi Reguler
Implementasi Split dan Bergabung (Fungsional)
Tidak tahu terlalu banyak tentang bagaimana ekspresi reguler bekerja di belakang layar dalam hal efisiensi, saya cenderung condong ke arah pemisahan dan bergabung dengan implementasi di masa lalu tanpa memikirkan kinerja. Ketika saya bertanya-tanya mana yang lebih efisien, dan berapa margin, saya menggunakannya sebagai alasan untuk mencari tahu.
Di mesin Chrome Windows 8 saya, implementasi berbasis ekspresi reguler adalah yang tercepat , dengan implementasi split dan join menjadi 53% lebih lambat . Berarti ekspresi reguler dua kali lebih cepat untuk input lorem ipsum yang saya gunakan.
Lihat patokan ini menjalankan dua implementasi ini terhadap satu sama lain.
Seperti dicatat dalam komentar di bawah ini oleh @ThomasLeduc dan lainnya, mungkin ada masalah dengan implementasi berbasis ekspresi reguler jika
search
berisi karakter tertentu yang dicadangkan sebagai karakter khusus dalam ekspresi reguler . Implementasi mengasumsikan bahwa penelepon akan lolos string sebelumnya atau hanya akan melewati string yang tanpa karakter dalam tabel di Regular Expressions (MDN).MDN juga menyediakan implementasi untuk keluar dari ikatan kami. Akan lebih baik jika ini juga dibakukan sebagai
RegExp.escape(str)
, tapi sayangnya, itu tidak ada:Kita bisa memanggil
escapeRegExp
dalamString.prototype.replaceAll
implementasi kami , namun, saya tidak yakin seberapa banyak ini akan mempengaruhi kinerja (bahkan potensial untuk string yang tidak diperlukan melarikan diri, seperti semua string alfanumerik).sumber
Menggunakan ekspresi reguler dengan
g
set bendera akan menggantikan semua:Lihat di sini juga
sumber
var sourceText
menghitung jumlah instance (numOfInstances
) menggunakansubstring
atau membagi dan menghitung panjang (di antara strategi lain)thatWhichYouWantToReplace
kemudian lakukanfor (var i = 0; i < numOfInstances; i++){ sourceText = sourceText.replace('thatWhichYouWantToReplace', '');
} atau bahkan lebih mudah hanya menggunakan loop sementara (while sourceText.indexOf(thatWhichYouWantToReplace > -1){ sourceText = sourceText.replace(...)
) tapi saya tidak melihat mengapa Anda ingin melakukannya dengan cara itu ketika menggunakan/g
sangat mudah dan mungkin lebih banyak pemain.Inilah fungsi prototipe string berdasarkan jawaban yang diterima:
EDIT
Jika
find
kehendak Anda mengandung karakter khusus maka Anda perlu menghindarinya:Fiddle: http://jsfiddle.net/cdbzL/
sumber
find
berisi karakter seperti.
atau$
yang memiliki makna khusus di regex?var str = this
menciptakan referensi kedua ke string yang tidak dapat diubah, yang manareplace
metode ini diterapkan, yang pada gilirannya mengembalikan string yang tidak dapat diubah baru . fungsi prototipe ini mengembalikan string baru yang tidak dapat diubah, jika tidak, Anda akan dapat menulissomeStrVar.replaceAll('o', '0');
dansomeStrVar
akan diubah. Sebagai gantinya, Anda harus menulissomeStrVar = someStrVar.replaceAll('o', '0');
<- menugaskan kembali untuk mengatur var untuk memegang string baru yang tidak dapat diubah . tidak ada jalan lain untuk itu. Coba di konsol:x = 'foobar'; x.replaceAll('o', '0'); x;
Memperbarui:
Agak terlambat untuk pembaruan, tetapi karena saya baru saja menemukan pertanyaan ini, dan memperhatikan bahwa jawaban saya sebelumnya bukanlah jawaban yang saya sukai. Karena pertanyaan melibatkan penggantian satu kata, sungguh luar biasa tidak ada yang berpikir untuk menggunakan batas kata (
\b
)Ini adalah regex sederhana yang menghindari penggantian bagian kata dalam kebanyakan kasus. Namun, tanda hubung
-
masih dianggap sebagai batas kata. Jadi kondisional dapat digunakan dalam kasus ini untuk menghindari penggantian string seperticool-cat
:pada dasarnya, pertanyaan ini sama dengan pertanyaan di sini: Javascript ganti "'" dengan "' '"
@ Mike, periksa jawaban yang saya berikan di sana ... regexp bukan satu-satunya cara untuk mengganti beberapa kemunculan subsrting, jauh dari itu. Berpikir fleksibel, pikirkan split!
Atau, untuk mencegah penggantian bagian kata - yang mana jawaban yang disetujui juga akan berlaku! Saya bisa mengatasi masalah ini menggunakan ekspresi reguler yang, saya akui, agak lebih kompleks dan sebagai hasilnya, sedikit lebih lambat, juga:
Outputnya sama dengan jawaban yang diterima, namun, menggunakan ekspresi / cat / g pada string ini:
Ups memang, ini mungkin bukan yang Anda inginkan. Apa itu? IMHO, sebuah regex yang hanya menggantikan 'kucing' dengan persyaratan. (Yaitu bukan bagian dari kata), seperti:
Dugaan saya adalah, ini memenuhi kebutuhan Anda. Tentu saja, ini tidak sepenuhnya tahan, tetapi itu sudah cukup untuk Anda memulainya. Saya sarankan membaca lebih banyak di halaman-halaman ini. Ini terbukti bermanfaat dalam menyempurnakan ungkapan ini untuk memenuhi kebutuhan spesifik Anda.
http://www.javascriptkit.com/jsref/regexp.shtml
http://www.regular-expressions.info
Penambahan akhir:
Mengingat bahwa pertanyaan ini masih mendapat banyak pandangan, saya pikir saya mungkin menambahkan contoh yang
.replace
digunakan dengan fungsi panggilan balik. Dalam hal ini, ia secara dramatis menyederhanakan ekspresi dan bahkan memberikan lebih banyak fleksibilitas, seperti mengganti dengan huruf besar yang benar atau mengganti keduanyacat
dancats
sekaligus:sumber
Cocokkan dengan ekspresi reguler global:
sumber
Untuk mengganti penggunaan satu kali:
Untuk mengganti beberapa kali gunakan:
sumber
replace(/\n/g, '<br/>')
Ini adalah metode yang paling umum dan mudah dibaca.
Metode 1:
Metode 2:
Metode 3:
Metode 4:
Keluaran:
sumber
Atau coba fungsi replaceAll dari sini:
Apa metode JavaScript yang berguna yang memperluas objek bawaan?
EDIT: Klarifikasi tentang replaceAll availability
Metode 'replaceAll' ditambahkan ke prototipe String. Ini berarti akan tersedia untuk semua objek string / literal.
Misalnya
sumber
Menggunakan
RegExp
dalam JavaScript dapat melakukan pekerjaan untuk Anda, cukup lakukan sesuatu seperti kode di bawah ini, jangan lupa/g
setelah yang menonjol untuk global :Jika Anda berpikir untuk menggunakan kembali, buat fungsi untuk melakukannya untuk Anda, tetapi itu tidak disarankan karena hanya satu fungsi baris, tetapi sekali lagi jika Anda banyak menggunakan ini, Anda dapat menulis sesuatu seperti ini:
dan cukup gunakan dalam kode Anda berulang-ulang seperti di bawah ini:
Tetapi seperti yang saya sebutkan sebelumnya, itu tidak akan membuat perbedaan besar dalam hal baris untuk ditulis atau kinerja, hanya caching fungsi dapat mempengaruhi beberapa kinerja lebih cepat pada string panjang dan juga praktik yang baik dari kode KERING jika Anda ingin menggunakan kembali.
sumber
Katakanlah Anda ingin mengganti semua 'abc' dengan 'x':
Saya mencoba untuk memikirkan sesuatu yang lebih sederhana daripada memodifikasi prototipe string.
sumber
Gunakan ekspresi reguler:
sumber
Mengganti tanda kutip tunggal:
sumber
// lilitkan sampai jumlah kejadian mencapai 0. ATAU cukup salin / tempel
sumber
.indexOf
dalam variabel, dan gunakan variabel ini sebagai parameter kedua.indexOf
(dikurangi panjang kata kunci, ditambah panjang string pengganti).bekerja lebih baik untuk saya daripada jawaban di atas. jadi
new RegExp("abc", 'g')
buat RegExp yang cocok dengan semua kemunculan ('g'
bendera) teks ("abc"
). Bagian kedua adalah apa yang akan diganti, dalam kasus Anda string kosong (""
).str
adalah string, dan kita harus menimpanya, karenareplace(...)
hanya mengembalikan hasil, tetapi bukan menimpa. Dalam beberapa kasus, Anda mungkin ingin menggunakannya.sumber
Ini adalah versi tercepat yang tidak menggunakan ekspresi reguler .
JSPF direvisi
Ini hampir dua kali lebih cepat dari metode split dan join.
Seperti yang ditunjukkan dalam komentar di sini, ini tidak akan berfungsi jika
omit
variabel Anda berisiplace
, seperti pada:,replaceAll("string", "s", "ss")
karena itu akan selalu dapat menggantikan kemunculan kata lainnya.Ada jsperf lain dengan varian pada rekursif saya yang lebih cepat ( http://jsperf.com/replace-all-vs-split-join/12 )!
sumber
if(place.replace(omit) === omit) {
Tidak cocok, jadi aman untuk menggunakan ganti loop} else {
Cocokkan jadi gunakan metode yang berbeda seperti split dan bergabung}
Performa
Hari ini 27.12.2019 Saya melakukan tes pada macOS v10.13.6 (High Sierra) untuk solusi yang dipilih.
Kesimpulan
str.replace(/abc/g, '');
( C ) adalah cross-browser solusi cepat baik untuk semua string.split-join
( A, B ) ataureplace
( C, D ) cepatwhile
( E, F, G, H ) lambat - biasanya ~ 4 kali lebih lambat untuk string kecil dan sekitar ~ 3000 kali (!) Lebih lambat untuk string panjangSaya juga membuat solusi sendiri. Sepertinya saat ini adalah yang terpendek yang melakukan pekerjaan pertanyaan:
Tampilkan cuplikan kode
Detail
Pengujian dilakukan pada Chrome 79.0, Safari 13.0.4 dan Firefox 71.0 (64 bit). Tes
RA
danRB
gunakan rekursi. HasilString pendek - 55 karakter
Anda dapat menjalankan tes pada mesin Anda DI SINI . Hasil untuk Chrome:
String panjang: 275 000 karakter
Solusi rekursif RA dan RB memberikan
Untuk karakter 1M mereka bahkan memecahkan Chrome
Saya mencoba melakukan tes untuk 1M karakter untuk solusi lain, tetapi E, F, G, H membutuhkan banyak waktu sehingga browser meminta saya untuk memecahkan skrip jadi saya mengecilkan string uji menjadi 275 ribu karakter. Anda dapat menjalankan tes pada mesin Anda DI SINI . Hasil untuk Chrome
Kode yang digunakan dalam tes
Tampilkan cuplikan kode
sumber
Jika yang ingin Anda temukan sudah ada dalam string, dan Anda tidak memiliki regex escaper berguna, Anda bisa menggunakan join / split:
sumber
sumber
Saya suka metode ini (kelihatannya sedikit lebih bersih):
sumber
Cara paling sederhana untuk ini tanpa menggunakan regex apa pun dibagi dan bergabung seperti kode di sini:
sumber
http://jsfiddle.net/ANHR9/
sumber
sumber
Jika string berisi pola yang mirip seperti
abccc
, Anda dapat menggunakan ini:sumber
Jawaban sebelumnya terlalu rumit. Cukup gunakan fungsi ganti seperti ini:
Contoh:
sumber
Jika Anda mencoba memastikan bahwa string yang Anda cari tidak akan ada bahkan setelah penggantian, Anda perlu menggunakan loop.
Sebagai contoh:
Ketika selesai, Anda masih akan memiliki 'test abc'!
Loop paling sederhana untuk menyelesaikan ini adalah:
Tapi itu menjalankan penggantian dua kali untuk setiap siklus. Mungkin (beresiko ditolak) yang dapat digabungkan untuk bentuk yang sedikit lebih efisien tetapi kurang mudah dibaca:
Ini bisa sangat berguna saat mencari string duplikat.
Misalnya, jika kami memiliki 'a ,,, b' dan kami ingin menghapus semua koma rangkap.
[Dalam hal ini, seseorang bisa melakukan .replace (/, + / g, ','), tetapi pada titik tertentu regex menjadi kompleks dan cukup lambat untuk diulang.]
sumber
Meskipun orang telah menyebutkan penggunaan regex tetapi ada pendekatan yang lebih baik jika Anda ingin mengganti teks terlepas dari kasus teks. Seperti huruf besar atau kecil. Gunakan sintaksis di bawah ini
Anda dapat merujuk contoh terperinci di sini .
sumber
Anda cukup menggunakan metode di bawah ini
sumber
Cukup tambahkan
/g
untuk
/g
berarti globalsumber