Menu

Regex di C#: Match, Replace, Split dan Group dengan Contoh

Cara memakai regular expression di C# dengan System.Text.RegularExpressions: IsMatch, Match, dan Matches, group bernomor dan bernama, Replace dengan substitusi dan lambda, Split, RegexOptions, string verbatim untuk pola, validasi input, timeout, dan attribute GeneratedRegex dari .NET 7.

Halaman ini dilengkapi editor yang bisa dijalankan. Edit, jalankan, dan lihat output-nya seketika.

Regular expression (regex) adalah pola yang menggambarkan teks: "empat digit, tanda hubung, dua digit", "kata yang diawali huruf kapital", "apa pun di antara kurung siku". Di C#, class Regex di System.Text.RegularExpressions mencari, mengambil, mengganti, dan memecah teks dengan pola seperti itu.

IsMatch, Match, dan Matches

Tiga method mencakup sebagian besar pencarian. IsMatch menjawab ya atau tidak, Match mengembalikan kecocokan pertama, dan Matches mengembalikan semuanya:

Output:

True
2026-03-14 at index 22
4 matches:
  1042
  2026
  1043
  2026
Success: False, Value: []

Match yang gagal tidak mengembalikan null: ia mengembalikan Match dengan Success bernilai false dan Value yang kosong. Selalu periksa Success sebelum memakai sebuah kecocokan.

Pencarian empat digit tadi menunjukkan bagaimana pola bisa menangkap lebih banyak dari yang dimaksud. \b\d{4}\b berarti "tepat empat digit sebagai satu kata utuh", dan tahun di dalam tanggal ikut memenuhi syarat, karena - adalah batas kata. Perketat polanya agar sesuai maksudmu, misalnya (?<=Order |order )\d+, atau pakai group, yang dibahas berikutnya.

String verbatim untuk pola

Sintaks regex memakai backslash di mana-mana (\d, \s, \b), begitu juga escape string di C#. Di string biasa, "\d" bahkan tidak bisa dikompilasi (CS1009, escape sequence tidak dikenal) dan "\b" dikompilasi menjadi karakter backspace, sehingga polanya berubah tanpa ketahuan. Tulis pola sebagai string verbatim dengan @, tempat backslash hanyalah backslash biasa:

var a = new Regex("\\d+\\.\\d{2}");   // escaped twice: hard to read
var b = new Regex(@"\d+\.\d{2}");     // verbatim: what the regex engine sees

Di string verbatim, tanda kutip ganda ditulis "". Raw string literal di C# 11 ("""...""") bahkan tidak perlu itu.

Group: mengambil bagian dari kecocokan

Tanda kurung membuat sebuah group, dan teks setiap group tersedia setelah pencocokan. Group dinomori mulai dari 1 sesuai urutan kurung bukanya; group 0 adalah seluruh kecocokan. Named group, (?<name>...), lebih mudah dibaca dan tetap aman saat polanya diedit:

Output:

2026-03-14
ERROR
payments
Card declined for order 1042
60 by 90, area 5400

[ dan ] punya arti di regex (sebuah character class), jadi untuk mencocokkan kurung siku apa adanya kamu butuh \[ dan \]. Hal yang sama berlaku untuk . * + ? ( ) { } ^ $ | \. Untuk mencocokkan string dari pengguna apa adanya di dalam pola, lewatkan string itu ke Regex.Escape, yang melakukan escape pada metakarakter untukmu: Regex.Escape("price (USD)") mengembalikan price\ \(USD\) (spasi juga ikut diberi escape, dan itu tidak berbahaya).

Tanda kurung yang hanya mengelompokkan tanpa menangkap ditulis (?:...). Bentuk ini menjaga penomoran group tetap rapi dan sedikit lebih cepat.

Replace: substitusi dan lambda

Regex.Replace mengganti setiap kecocokan. Di string pengganti, $1 menyisipkan group 1, ${name} menyisipkan named group, dan $0 menyisipkan seluruh kecocokan. Untuk apa pun yang tidak bisa diungkapkan lewat template, berikan sebuah fungsi (biasanya lambda) yang menerima setiap Match dan mengembalikan penggantinya:

Output:

Invoiced 14/03/2026, paid 02/04/2026.
too many spaces
Card **** **** **** 1234
Tea 2.75, Scone 3.52, Jam 1.10

Masker kartu itu memakai lookahead, (?=...): ia mencocokkan sebuah digit hanya jika diikuti empat digit lagi, tanpa memakai digit-digit itu. Lookaround ((?=...), (?!...), (?<=...), (?<!...)) menguji konteks tanpa memasukkannya ke dalam kecocokan, dan itulah yang membuat satu Replace saja bisa menjaga empat digit terakhir tetap utuh.

Untuk teks biasa tanpa pola, string.Replace lebih sederhana dan lebih cepat; pakai Regex.Replace jika hal yang ingin diganti bervariasi.

Split

Regex.Split memecah teks di setiap kecocokan sebuah pola, sehingga bisa menangani pemisah yang bervariasi:

Output:

csharp / dotnet / regex / tutorial / beginner
Order Shipped Event Handler

Jika polanya berisi capturing group, Regex.Split ikut memasukkan pemisah yang tertangkap ke dalam hasilnya; pakai (?:...) jika kamu tidak menginginkannya.

RegexOptions

Option mengubah perilaku seluruh pola. Gabungkan dengan |:

Output:

1
2
error INFO Error
True

Yang akan sering kamu pakai:

  • IgnoreCase: pencocokan yang tidak peka huruf besar kecil (bentuk inline-nya (?i)).
  • Multiline: ^ dan $ cocok di awal dan akhir setiap baris, bukan hanya di awal dan akhir seluruh string.
  • Singleline: . juga cocok dengan \n (secara default ia cocok dengan karakter apa pun kecuali baris baru).
  • IgnorePatternWhitespace: spasi di dalam pola diabaikan dan # memulai komentar, untuk pola panjang yang ditulis dalam beberapa baris.
  • CultureInvariant: bersama IgnoreCase, membandingkan tanpa aturan dari culture yang sedang aktif.
  • Compiled: melakukan compile pola menjadi IL sekali, untuk regex yang dipakai berkali-kali.

Validasi input: anchor dan soal email

Untuk validasi, pasang anchor ^ dan $ pada pola, karena jika tidak, pola akan lolos begitu sebagian input cocok:

Output:

PT-1000    loose=True  strict=True
pt-1000    loose=False strict=False
XPT-1000Y  loose=True  strict=False
PT-10      loose=False strict=False
ana@example.com   True
ana@example       False
ana @example.com  False
ana@@example.com  False

Pola email itu hanya memeriksa bentuknya: sesuatu tanpa spasi atau @, satu @, lalu domain dengan titik. Itu memang disengaja. Tata bahasa alamat yang sebenarnya (RFC 5322) mengizinkan local part yang diapit tanda kutip, komentar, dan domain berupa alamat IP; pola yang mencoba mencakup semuanya bisa sampai ratusan karakter dan tetap menolak alamat valid yang benar-benar dipakai orang. Selain itu, alamat yang sintaksnya sempurna pun masih bisa gagal menerima email. Periksa bentuknya, lalu kirim email konfirmasi. System.Net.Mail.MailAddress menawarkan cara lain untuk memeriksa bentuk jika kamu tidak ingin menulis pola.

Performa: method static, instance, compiled

Method static (Regex.IsMatch(input, pattern)) melakukan parsing pola dan menyimpannya di cache kecil (15 pola secara default), jadi pemanggilan berulang dengan pola yang sama itu murah. Untuk pola yang dipakai di perulangan yang sering dijalankan, buat satu instance Regex dan simpan di field static readonly; tambahkan RegexOptions.Compiled jika pola itu dijalankan ribuan kali, dengan konsekuensi awal yang lebih lambat demi pencocokan yang lebih cepat.

Timeout dan catastrophic backtracking

Beberapa pola butuh waktu eksponensial untuk input tertentu. Contoh klasiknya adalah quantifier bersarang seperti ^(a+)+$ terhadap "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa!": mesin regex mencoba setiap cara membagi a di antara kedua + sebelum menyerah. Di web server, satu input seperti itu dari pengguna bisa membuat satu core CPU sibuk penuh (serangan "ReDoS"). Beri timeout pada setiap regex yang menangani input yang tidak tepercaya:

var pattern = new Regex(@"^(\w+\s?)*$", RegexOptions.None, TimeSpan.FromMilliseconds(100));
try
{
    bool ok = pattern.IsMatch(userInput);
}
catch (RegexMatchTimeoutException)
{
    // treat as invalid input
}

Setiap method static juga punya overload yang menerima timeout. .NET 7 juga menambahkan RegexOptions.NonBacktracking, mesin yang menjamin waktu linear dengan mengorbankan beberapa fitur (lookaround, backreference).

GeneratedRegex (.NET 7)

.NET 7 menambahkan source generator yang mengubah pola menjadi kode C# biasa saat kompilasi. Kamu mendapat kecepatan Compiled tanpa biaya start-up, kode yang dihasilkan bisa dibaca di IDE, dan cara ini bekerja dengan trimming dan Native AOT:

public static partial class Patterns
{
    [GeneratedRegex(@"^[A-Z]{2}-\d{4}$", RegexOptions.IgnoreCase)]
    public static partial Regex ProductCode();
}

bool ok = Patterns.ProductCode().IsMatch("pt-1000");   // True

Di .NET 7 dan sesudahnya, inilah bentuk yang direkomendasikan untuk pola apa pun yang sudah diketahui saat kompilasi.

Kesalahan umum

  • Tidak memakai anchor saat validasi. Tanpa ^...$, IsMatch menerima input yang hanya mengandung sebuah kecocokan.
  • String biasa untuk pola. "\b" adalah backspace, bukan batas kata. Pakai @"...".
  • Karakter khusus tanpa escape. . cocok dengan karakter apa pun; 3.50 sebagai pola juga cocok dengan 3x50. Escape dengan \., atau dengan Regex.Escape untuk input pengguna.
  • Quantifier yang greedy. <.*> pada <b>bold</b> mencocokkan seluruh string. Pakai versi lazy .*? atau negated class [^>]*.
  • Tidak ada timeout untuk input yang tidak tepercaya. Quantifier bersarang bisa membuat sebuah request macet.
  • Regex untuk format terstruktur. HTML, JSON, dan CSV dengan tanda kutip butuh parser, bukan pola.

Pertanyaan yang sering diajukan

Bagaimana cara memakai regex di C#?

Tambahkan using System.Text.RegularExpressions; lalu panggil method static di Regex: Regex.IsMatch(input, pattern) mengembalikan bool, Regex.Match mengembalikan kecocokan pertama, Regex.Matches mengembalikan semuanya, Regex.Replace melakukan penggantian, dan Regex.Split memecah teks. Tulis pola sebagai string verbatim, @"\d+", agar backslash sampai ke mesin regex tanpa berubah.

Bagaimana cara mengambil nilai group dari hasil regex di C#?

Beri tanda kurung di sekitar bagian yang kamu inginkan, lalu baca match.Groups[1].Value (group dinomori mulai dari 1; group 0 adalah seluruh kecocokan). Named group lebih jelas: (?<year>\d{4}) dibaca dengan match.Groups["year"].Value. Periksa match.Success lebih dulu, karena kecocokan yang gagal punya group kosong, bukan null.

Bagaimana cara mengganti teks dengan regex di C#?

Regex.Replace(input, pattern, replacement) mengganti setiap kecocokan. Teks pengganti bisa merujuk ke group: $1 untuk group bernomor, ${name} untuk group bernama, $0 untuk seluruh kecocokan. Untuk logika yang tidak bisa diungkapkan lewat template, berikan lambda: Regex.Replace(text, @"\d+", m => (int.Parse(m.Value) * 2).ToString()).

Bagaimana cara membuat regex C# tidak peka huruf besar kecil?

Berikan RegexOptions.IgnoreCase: Regex.IsMatch(input, "error", RegexOptions.IgnoreCase). Option bisa digabung dengan |, misalnya RegexOptions.IgnoreCase | RegexOptions.Multiline. Kamu juga bisa mengaktifkannya di dalam pola dengan (?i).

Bagaimana cara memvalidasi alamat email dengan regex di C#?

Pola seperti ^[^@\s]+@[^@\s]+\.[^@\s]+$ menangkap salah ketik yang jelas (tidak ada @, ada spasi, tidak ada titik di domain) dan biasanya hanya itu yang dibutuhkan sebuah form. Regex tidak bisa benar-benar memvalidasi alamat: tata bahasa lengkapnya mengizinkan bentuk yang tidak bisa ditangani pola praktis mana pun, dan alamat yang sintaksnya benar belum tentu ada. Periksa bentuk dasarnya, lalu konfirmasi dengan mengirim email verifikasi.

Ilustrasi bahasa pemrograman di Coddy

Belajar coding dengan Coddy

Mulai