replace() mencari bagian teks yang cocok dengan pola, lalu menggantinya. Bayangin Bu Ratna mau merekap PO ke spreadsheet. Chat-nya berantakan: harga ditulis Rp85.000, 90rb, dan 75k; nomor HP ada tiga gaya. Spreadsheet butuh satu bentuk: angka bulat dan nomor +62. Ini mirip fitur "Cari dan Ganti" di Word, bedanya yang dicari pola, dan penggantinya boleh dihitung dulu. Di akhir pelajaran, chat kita jadi CSV seperti ini:
nama,nomor,total
Dina,+6281234567890,170000
Bayu,+6285711223344,165000
Sari,+6281298765432,255000
🧪 Tebakan cepat: sebelum chat dibagikan ke grup, nomor HP disensor dengan
chat.replace(/(?:\+62 ?|0)8\d{2}[- ]?\d{4}[- ]?\d{3,4}/, "[nomor HP]"). Ada tiga nomor HP di chat. Berapa yang tersensor? Tebak dulu, jawabannya ada di bagian "replace()dan flagg".
replace() dan flag g
const tanpaG = chat.replace(/(?:\+62 ?|0)8\d{2}[- ]?\d{4}[- ]?\d{3,4}/, "[nomor HP]");
const denganG = chat.replace(/(?:\+62 ?|0)8\d{2}[- ]?\d{4}[- ]?\d{3,4}/g, "[nomor HP]");
console.log(tanpaG.match(/\[nomor HP\]/g).length); // 1
console.log(denganG.match(/\[nomor HP\]/g).length); // 3
console.log(denganG.split("\n")[2]);
// '[12/03/26 08.20] Bayu: Saya kastengel 1, putri salju 1. Total brp? hp [nomor HP]'
- Tanpa flag
g,replace()cuma mengganti kecocokan pertama: nomor Dina. Nomor Bayu dan Sari tetap kelihatan. Itu jawaban tebakannya. Dengang, semua kecocokan diganti. - Pola berupa teks biasa juga cuma mengganti yang pertama:
"0812-3456-7890".replace("-", "")memberi'08123456-7890'. Untuk semua:/-/g, ataureplaceAll("-", ""). replace()gak mengubahchat. String di JavaScript gak bisa diubah, jadi dia mengembalikan string baru. Simpan hasilnya ke variabel.
Teks pengganti: $1, lt;nama>, amp;
Di teks pengganti, beberapa kode $ punya arti khusus:
| Kode | Diganti dengan |
|---|---|
amp; |
seluruh teks yang cocok |
$1, $2, ... |
isi group 1, group 2, ... |
lt;nama> |
isi named group (?<nama>...) |
$ |
tanda $ biasa |
console.log("2024-01-15".replace(/(\d{4})-(\d{2})-(\d{2})/, "$3/$2/$1")); // '15/01/2024'
console.log("Kode PO-0412".replace(/PO-\d{4}/, "[amp;]")); // 'Kode [PO-0412]'
console.log("Total 85000".replace(/\d+/, "$amp;")); // 'Total $85000'
console.log("[email protected]".replace(/^(.)[^@]*(@.*)$/, "$1***$2")); // 'd***@example.com'
const waktu = /\[(?<hari>\d{2})\/(?<bulan>\d{2})\/(?<tahun>\d{2}) (?<jam>\d{2})\.(?<menit>\d{2})\]/g;
console.log(chat.replace(waktu, "[20lt;tahun>-lt;bulan>-lt;hari> lt;jam>:lt;menit>]").split("\n")[0]);
// '[2026-03-12 08:15] Ratna (Admin): Open PO kue Lebaran! ...'
$3/$2/$1menyusun ulang tiga group: tahun-bulan-hari jadi hari/bulan/tahun.- Sensor email:
(.)menangkap huruf pertama,[^@]*sisa nama sebelum@(gak ditangkap),(@.*)tanda@sampai akhir. Penggantinya huruf pertama, tiga bintang, lalu domain. - Waktu chat
[12/03/26 08.15]jadi[2026-03-12 08:15]lewat named group:lt;tahun>lebih gampang dibaca daripada$3.
Function pengganti: harga jadi angka
Teks pengganti cuma bisa menyusun ulang. Untuk menghitung, berikan function. Function itu dipanggil sekali untuk tiap kecocokan, dan yang dia return jadi penggantinya.
"Kastengel 90rb".replace(/(\d+)(rb|k)/, (...args) => { console.log(args); return ""; });
// ['90rb', '90', 'rb', 10, 'Kastengel 90rb']
const harga = /Rp(\d{1,3}(?:\.\d{3})+)|(\d+)(?:rb|k)\b/g;
const angka = chat.replace(harga, (cocok, rp, singkat) =>
rp ? rp.replace(/\./g, "") : String(singkat * 1000)
);
console.log(angka.split("\n")[0]);
// '... *Nastar* 85000/toples, *Kastengel* 90000, *Putri Salju* 75000. Kode PO-0412'
- Argumen function berurutan: seluruh kecocokan, isi tiap group, posisinya (
10), lalu teks utuhnya. Kalau polanya punya named group, ada satu argumen lagi di ujung: objectgroups. - Pola harga punya dua pilihan.
Rp85.000cocok dengan pilihan kiri:rpberisi'85.000',singkatberisiundefined, lalu titiknya dibuang.90rbcocok dengan pilihan kanan:rpundefined,singkat'90', lalu dikali 1000. - Hasil function diubah jadi teks.
String(...)menuliskannya terang-terangan.
Huruf besar dan kecil
Function pengganti juga dipakai untuk mengubah huruf:
console.log("halo dunia javascript".replace(/\b\w/g, (h) => h.toUpperCase())); // 'Halo Dunia Javascript'
console.log("hello world".replace(/(^|\s)(\w)/g, (_, p1, p2) => p1 + p2.toUpperCase())); // 'Hello World'
const rapiHuruf = chat.replace(/\b[A-Z]{4,}\b/g, (kata) => kata[0] + kata.slice(1).toLowerCase());
console.log(rapiHuruf.split("\n")[4]);
// '[12/03/26 08.25] Sari: Nastar 3 toples = 255rb kan? no saya 081298765432, kirim tgl 25/03'
\b\wcocok dengan huruf pertama tiap kata, jadi cuma huruf itu yang dibesarkan. Sisanya gak disentuh.(^|\s)(\w): group 1 awal teks atau spasi, group 2 huruf pertama kata._cuma nama untuk argumen pertama (seluruh kecocokan) yang gak dipakai.[A-Z]{4,}mengambil kata kapital semua yang minimal 4 huruf:NASTARjadiNastar. Singkatan pendek sepertiPO,WA, danBCAaman.
Dari chat ke CSV
Sekarang semuanya digabung: rapikan harga dan nomor HP (pola HP dari pelajaran Common Patterns: URL & Phone), lalu ambil nama, nomor, dan total tiap pembeli.
const rapi = chat
.replace(/Rp(\d{1,3}(?:\.\d{3})+)|(\d+)(?:rb|k)\b/g, (cocok, rp, singkat) =>
rp ? rp.replace(/\./g, "") : String(singkat * 1000))
.replace(/(?:\+62 ?|0)8\d{2}[- ]?\d{4}[- ]?\d{3,4}/g, (hp) =>
hp.replace(/[^\d+]/g, "").replace(/^0/, "+62"));
const csv = ["nama,nomor,total"];
for (const nama of new Set(rapi.match(/(?<=\] )\w+(?=:)/g))) {
const baris = rapi.match(new RegExp(`^.*\\b${nama}\\b.*
Replace & Transform — Regex — Hyper Sheets
, "gm")).join(" ");
const nomor = baris.match(/\+62\d+/)?.[0] ?? "";
const total = baris.match(/(?:total|transfer|=) (\d+)/)?.[1] ?? "";
csv.push(`${nama},${nomor},${total}`);
}
console.log(csv.join("\n")); // CSV di awal pelajaran
- Dua
replace()berantai: hasil yang pertama jadi teks untuk yang kedua. (?<=\] )\w+(?=:)mengambil nama pengirim:Dina,Bayu,Sari.Ratna (Admin)gak ikut karena ada spasi dan kurung sebelum titik dua.- Tiap nama mengumpulkan semua baris yang menyebutnya, termasuk
@Bayu total 165000dari admin, lalu nomor dan totalnya diambil dari situ. - Tanpa langkah rapikan, CSV-nya rusak: nomor
+62 857-1122-3344gak cocok dengan\+62\d+karena ada spasi, sesudahtransferdiRp170.000gak ada angka, dan dari255rbcuma terambil255. Yang gak ketemu jadi teks kosong lewat?.[0] ?? "", bukan error.
⚠️ Jebakan yang sering ketemu
- Lupa
g. Cuma kecocokan pertama yang diganti, dan sisanya lolos tanpa error. - Lupa
returndi function berkurung kurawal."90rb".replace(/(\d+)rb/, (cocok, n) => { n * 1000; })memberi'undefined'. Tulisreturn, atau pakai bentuk pendek tanpa kurung kurawal. $di teks pengganti.$1,amp;, danlt;nama>punya arti khusus. Mau tanda dolar biasa? Tulis$.- Pola ubah-huruf terlalu luas.
\b[A-Z]{2,}\bikut mengubahPO-0412jadiPo-0412danBCAjadiBca. - Parse HTML dengan regex.
"<p>Halo <b>Dina</b></p>".replace(/<[^>]*>/g, "")memberi'Halo Dina', tapi'<p title="a>b">Halo</p>'jadi'b">Halo'. HTML punya struktur bersarang dan tanda yang artinya tergantung konteks (di dalam atribut, komentar, script), dan regex gak bisa melacak itu. Pakai parser:DOMParserdi browser, dan DOMPurify untuk membersihkan HTML dari pengguna.
TL;DR: replace() mengembalikan string baru: tanpa g cuma kecocokan pertama yang diganti, dengan g semuanya. Di teks pengganti, $1, $2 adalah isi group, lt;nama> named group, amp; seluruh kecocokan, $ dolar biasa: "2024-01-15".replace(/(\d{4})-(\d{2})-(\d{2})/, "$3/$2/$1") memberi "15/01/2024", dan /^(.)[^@]*(@.*)$/ dengan "$1***$2" menyensor email jadi d***@example.com. Function pengganti menerima seluruh kecocokan lalu tiap group, dan yang di-return jadi penggantinya: dipakai untuk menghitung (90rb jadi 90000, Rp85.000 jadi 85000) dan mengubah huruf (/\b\w/g dengan toUpperCase(), atau (_, p1, p2) => p1 + p2.toUpperCase() untuk /(^|\s)(\w)/g). Beberapa replace() berantai merapikan chat jadi CSV. Jangan parse HTML dengan regex: pakai parser.