Pertanyaan Bagaimana cara mengganti semua kemunculan string dalam JavaScript?


Saya memiliki string ini:

"Test abc test test abc test test test abc test test abc"

Perbuatan

str = str.replace('abc', '');

tampaknya hanya menghapus kejadian pertama abc dalam string di atas. Bagaimana saya bisa mengganti semua kejadian itu?


3164
2017-07-17 17:53


asal


Jawaban:


Demi kelengkapan, saya harus memikirkan metode mana 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 sebagai ekstensi pada prototipe String hanya untuk tujuan ilustrasi, menunjukkan implementasi yang berbeda dari metode standar hipotetis pada String prototipe built-in.


Implementasi Ekspresi Reguler

String.prototype.replaceAll = function(search, replacement) {
    var target = this;
    return target.replace(new RegExp(search, 'g'), replacement);
};

Split dan Gabung (Fungsional) Implementasi

String.prototype.replaceAll = function(search, replacement) {
    var target = this;
    return target.split(search).join(replacement);
};

Tidak tahu terlalu banyak tentang bagaimana ekspresi reguler bekerja di belakang layar dalam hal efisiensi, saya cenderung condong ke arah perpecahan dan bergabung dengan implementasi di masa lalu tanpa memikirkan kinerja. Ketika saya bertanya-tanya mana yang lebih efisien, dan dengan batas apa, saya menggunakannya sebagai alasan untuk mencari tahu.

Pada mesin Windows 8 Chrome saya, implementasi berbasis ekspresi reguler adalah yang tercepat, dengan split dan bergabung dengan implementasi menjadi 53% lebih lambat. Berarti ekspresi reguler dua kali lebih cepat untuk input lorem ipsum yang saya gunakan.

Lihat ini patokan menjalankan dua implementasi ini terhadap satu sama lain.


Seperti tercantum dalam komentar di bawah ini oleh @ThomasLeduc dan lainnya, mungkin ada masalah dengan penerapan berbasis ekspresi reguler jika search mengandung karakter tertentu yang dicadangkan sebagai karakter khusus dalam ekspresi reguler. Implementasi mengasumsikan bahwa pemanggil akan keluar dari string sebelumnya atau hanya akan melewati string tanpa karakter di dalam tabel Ekspresi Reguler (MDN).

MDN juga menyediakan implementasi untuk melepaskan diri dari string kami. Akan lebih baik jika ini juga distandarkan sebagai RegExp.escape(str), tapi sayangnya, itu tidak ada:

function escapeRegExp(str) {
  return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); // $& means the whole matched string
}

Kami bisa menelepon escapeRegExp di dalam kami String.prototype.replaceAll implementasi, bagaimanapun, saya tidak yakin berapa banyak ini akan mempengaruhi kinerja (berpotensi bahkan untuk string yang tidak diperlukan untuk melarikan diri, seperti semua string alfanumerik).


1627
2017-07-12 01:46



str = str.replace(/abc/g, '');

Menanggapi komentar:

var find = 'abc';
var re = new RegExp(find, 'g');

str = str.replace(re, '');

Menanggapi Klik UpvoteKomentar, Anda dapat menyederhanakannya lebih lanjut:

function replaceAll(str, find, replace) {
    return str.replace(new RegExp(find, 'g'), replace);
}

catatan: Ekspresi reguler mengandung karakter khusus (meta), dan karena itu berbahaya untuk secara membabi buta menyampaikan argumen dalam find berfungsi di atas tanpa pra-memprosesnya untuk keluar dari karakter tersebut. Ini tercakup dalam Jaringan Pengembang Mozilla's Panduan JavaScript tentang Ekspresi Reguler, di mana mereka menyajikan fungsi utilitas berikut:

function escapeRegExp(str) {
    return str.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, "\\$1");
}

Jadi untuk membuat replaceAll() berfungsi di atas lebih aman, bisa dimodifikasi menjadi berikut jika Anda juga memasukkan escapeRegExp:

function replaceAll(str, find, replace) {
    return str.replace(new RegExp(escapeRegExp(find), 'g'), replace);
}

3586
2017-07-17 17:54



Catatan: Jangan gunakan ini dalam kode asli.

Sebagai alternatif untuk ekspresi reguler string sederhana, Anda bisa menggunakannya

str = "Test abc test test abc test...".split("abc").join("");

Pola umumnya adalah

str.split(search).join(replacement)

Ini digunakan lebih cepat dalam beberapa kasus daripada menggunakan replaceAll dan ekspresi reguler, tetapi itu tidak menjadi masalah lagi di browser modern. Jadi, ini seharusnya benar-benar hanya digunakan sebagai peretasan cepat agar tidak perlu melarikan diri dari ekspresi reguler, tidak dalam kode nyata.


1193
2017-07-17 20:29



Menggunakan ekspresi reguler dengan g set bendera akan menggantikan semua:

someString = 'the cat looks like a cat';
anotherString = someString.replace(/cat/g, 'dog');
// anotherString now contains "the dog looks like a dog"

Lihat di sini juga


505
2018-05-06 23:18



Berikut ini fungsi prototipe string berdasarkan jawaban yang diterima:

String.prototype.replaceAll = function (find, replace) {
    var str = this;
    return str.replace(new RegExp(find, 'g'), replace);
};

EDIT 

Jika Anda find akan berisi karakter khusus, maka Anda harus menghindarinya:

String.prototype.replaceAll = function (find, replace) {
    var str = this;
    return str.replace(new RegExp(find.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'), 'g'), replace);
};

Biola: http://jsfiddle.net/cdbzL/


90
2018-02-11 23:03



Memperbarui:

Ini agak terlambat untuk pembaruan, tetapi karena saya hanya tersandung pada pertanyaan ini, dan memperhatikan bahwa jawaban saya sebelumnya bukanlah yang saya senangi. Karena pertanyaan yang terlibat mengganti satu kata, tidak ada yang berpikir tentang penggunaan batas kata (\b)

'a cat is not a caterpillar'.replace(/\bcat\b/gi,'dog');
//"a dog is not a caterpillar"

Ini adalah regex sederhana yang menghindari mengganti sebagian kata dalam banyak kasus. Namun, sedikit saja - masih dianggap batas kata. Jadi kondisional dapat digunakan dalam kasus ini untuk menghindari mengganti string seperti cool-cat:

'a cat is not a cool-cat'.replace(/\bcat\b/gi,'dog');//wrong
//"a dog is not a cool-dog" -- nips
'a cat is not a cool-cat'.replace(/(?:\b([^-]))cat(?:\b([^-]))/gi,'$1dog$2');
//"a dog is not a cool-cat"

pada dasarnya, pertanyaan ini sama dengan pertanyaan di sini: Javascript mengganti "'" dengan "' '"

@Mike, periksa jawaban yang saya berikan di sana ... regexp bukan satu-satunya cara untuk menggantikan beberapa kemunculan subsrting, jauh dari itu. Pikirkan fleksibel, pikirkan perpecahan!

var newText = "the cat looks like a cat".split('cat').join('dog');

Atau, untuk mencegah mengganti suku kata - yang juga akan disetujui oleh jawaban yang disetujui! Anda dapat mengatasi masalah ini menggunakan ekspresi reguler yang, saya akui, agak lebih rumit dan sebagai hasil dari itu, sedikit lebih lambat, juga:

var regText = "the cat looks like a cat".replace(/(?:(^|[^a-z]))(([^a-z]*)(?=cat)cat)(?![a-z])/gi,"$1dog");

Outputnya sama dengan jawaban yang diterima, namun, menggunakan ekspresi / cat / g pada string ini:

var oops = 'the cat looks like a cat, not a caterpillar or coolcat'.replace(/cat/g,'dog');
//returns "the dog looks like a dog, not a dogerpillar or cooldog" ?? 

Ups memang, ini mungkin bukan yang Anda inginkan. Lalu apa itu? IMHO, regex yang hanya menggantikan 'kucing' secara kondisional. (yaitu bukan bagian dari kata), seperti:

var caterpillar = 'the cat looks like a cat, not a caterpillar or coolcat'.replace(/(?:(^|[^a-z]))(([^a-z]*)(?=cat)cat)(?![a-z])/gi,"$1dog");
//return "the dog looks like a dog, not a caterpillar or coolcat"

Tebakan saya adalah, ini memenuhi kebutuhan Anda. Tentu saja ini tidak sepenuhnya, tetapi seharusnya cukup untuk memulai. Saya akan merekomendasikan membaca lagi di halaman ini. Ini akan berguna 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 .replace digunakan dengan fungsi panggilan balik. Dalam hal ini, ini secara dramatis menyederhanakan ekspresi dan memberikan lebih banyak fleksibilitas, seperti mengganti dengan kapitalisasi yang benar atau mengganti keduanya cat dan cats sekaligus:

'Two cats are not 1 Cat! They\'re just cool-cats, you caterpillar'
   .replace(/(^|.\b)(cat)(s?\b.|$)/gi,function(all,char1,cat,char2)
    {
       //check 1st, capitalize if required
       var replacement = (cat.charAt(0) === 'C' ? 'D' : 'd') + 'og';
       if (char1 === ' ' && char2 === 's')
       {//replace plurals, too
           cat = replacement + 's';
       }
       else
       {//do not replace if dashes are matched
           cat = char1 === '-' || char2 === '-' ? cat : replacement;
       }
       return char1 + cat + char2;//return replacement string
    });
//returns:
//Two dogs are not 1 Dog! They're just cool-cats, you caterpillar

75
2018-03-01 10:02



Cocokkan dengan ekspresi reguler global:

anotherString = someString.replace(/cat/g, 'dog');

45
2018-05-06 23:23