Bir düzenli ifade (regex), metni tanımlayan bir desendir: "dört rakam, bir tire, iki rakam", "büyük harfle başlayan bir kelime", "köşeli parantezler arasındaki her şey". C#'ta System.Text.RegularExpressions içindeki Regex sınıfı bu tür desenlerle metin bulur, çıkarır, değiştirir ve böler.
IsMatch, Match ve Matches
Üç metot çoğu aramayı karşılar. IsMatch evet ya da hayır cevabı verir, Match ilk eşleşmeyi, Matches ise hepsini döndürür:
Çıktı:
True
2026-03-14 at index 22
4 matches:
1042
2026
1043
2026
Success: False, Value: []
Başarısız bir Match null döndürmez: Success'i false ve Value'su boş olan bir Match döndürür. Bir eşleşmeyi kullanmadan önce her zaman Success'i test edin.
Dört rakam araması, desenlerin nasıl amaçlanandan fazlasını yakaladığını gösterir. \b\d{4}\b "tam bir kelime olarak tam dört rakam" demektir ve tarihlerin içindeki yıllar da uyar, çünkü - bir kelime sınırıdır. Deseni kastettiğinizi söyleyecek şekilde sıkılaştırın, örneğin (?<=Order |order )\d+, ya da sıradaki grupları kullanın.
Desenler için verbatim string'ler
Regex sözdizimi her yerde ters eğik çizgi kullanır (\d, \s, \b), C# string kaçışları da öyle. Normal bir string'de "\d" derlenmez bile (CS1009, unrecognized escape sequence) ve "\b" bir geri silme karakterine derlenerek deseni sessizce değiştirir. Desenleri, ters eğik çizginin sadece ters eğik çizgi olduğu @ ile verbatim string'ler olarak yazın:
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
Bir verbatim string'de çift tırnak "" olarak yazılır. C# 11 ham string literal'leri ("""...""") bundan bile kaçınır.
Gruplar: bir eşleşmenin parçalarını çıkarmak
Parantezler bir grup oluşturur ve her grubun metni eşleşmeden sonra kullanılabilir. Gruplar açılış parantezlerinin sırasıyla 1'den numaralanır; 0. grup tüm eşleşmedir. Adlandırılmış gruplar, (?<name>...), okunması daha kolaydır ve desendeki düzenlemelerden etkilenmez:
Çıktı:
2026-03-14
ERROR
payments
Card declined for order 1042
60 by 90, area 5400
[ ve ]'nin regex'te bir anlamı vardır (bir karakter sınıfı), bu yüzden literal köşeli parantezleri eşleştirmek \[ ve \] gerektirir. Aynısı . * + ? ( ) { } ^ $ | \ için de geçerlidir. Kullanıcının verdiği bir string'i bir desenin içinde literal olarak eşleştirmek için onu meta karakterleri sizin için kaçıran Regex.Escape'ten geçirin: Regex.Escape("price (USD)") price\ \(USD\) döndürür (boşluklar da kaçırılır, bu zararsızdır).
Yakalamadan yalnızca gruplayan parantezler (?:...) olarak yazılır. Grup numaralandırmasını temiz tutarlar ve biraz daha hızlıdırlar.
Replace: yerine koymalar ve lambda'lar
Regex.Replace her eşleşmeyi değiştirir. Yerine konan string'de $1 1. grubu, ${name} adlandırılmış bir grubu ve $0 tüm eşleşmeyi ekler. Bir şablonun ifade edemediği her şey için, her Match'i alıp onun yerine konacak metni döndüren bir fonksiyon (genellikle bir lambda) verin:
Çıktı:
Invoiced 14/03/2026, paid 02/04/2026.
too many spaces
Card **** **** **** 1234
Tea 2.75, Scone 3.52, Jam 1.10
Kart maskesi bir lookahead kullanır, (?=...): bir rakamı yalnızca ardından dört rakam daha geliyorsa, onları tüketmeden eşleştirir. Lookaround'lar ((?=...), (?!...), (?<=...), (?<!...)) bağlamı eşleşmeye dahil etmeden test eder; tek bir Replace'in son dört rakamı bozmadan tutmasını sağlayan budur.
Desensiz düz metin için string.Replace daha basit ve hızlıdır; değiştirilecek şey değiştiğinde Regex.Replace'e başvurun.
Split
Regex.Split bir desenin her eşleşmesinde böler; bu, değişken ayırıcıları halleder:
Çıktı:
csharp / dotnet / regex / tutorial / beginner
Order Shipped Event Handler
Desen yakalayan gruplar içeriyorsa Regex.Split yakalanan ayırıcıları sonuca dahil eder; onları istemediğinizde (?:...) kullanın.
RegexOptions
Seçenekler tüm desenin nasıl davrandığını değiştirir. Onları | ile birleştirin:
Çıktı:
1
2
error INFO Error
True
Kullanacaklarınız:
IgnoreCase: harf duyarsız eşleştirme (satır içi biçimi(?i)).Multiline:^ve$yalnızca tüm string'in değil her satırın başında ve sonunda eşleşir.Singleline:.\nile de eşleşir (varsayılan olarak satır sonu dışında her karakterle eşleşir).IgnorePatternWhitespace: desendeki boşluklar yok sayılır ve#bir yorum başlatır; birkaç satıra yazılan uzun desenler için.CultureInvariant:IgnoreCaseile geçerli kültürün kuralları olmadan karşılaştırır.Compiled: birçok kez kullanılan bir regex için deseni bir kez IL'e derler.
Girdi doğrulamak: çapalar ve e-posta sorusu
Doğrulama için deseni ^ ve $ ile çapalayın, aksi halde girdinin bir kısmı eşleşir eşleşmez geçer:
Çıktı:
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
E-posta deseni yalnızca şekli kontrol eder: boşluk ya da @ içermeyen bir şey, bir @, noktalı bir alan adı. Bu bilinçlidir. Adreslerin gerçek dilbilgisi (RFC 5322) tırnaklı yerel kısımlara, yorumlara ve IP literal alan adlarına izin verir; onu kapsamaya çalışan desenler yüzlerce karaktere ulaşır ve yine de insanların gerçekten kullandığı geçerli adresleri reddeder. Ve sözdizimsel olarak kusursuz bir adres yine de geri dönebilir. Şekli kontrol edin, sonra bir onay e-postası gönderin. Desen yazmamayı tercih ederseniz System.Net.Mail.MailAddress başka bir şekil kontrolü sunar.
Performans: statik metotlar, örnekler, derlenmiş
Statik metotlar (Regex.IsMatch(input, pattern)) deseni parse eder ve küçük bir önbellekte (varsayılan olarak 15 desen) tutar, bu yüzden aynı desenle tekrarlanan çağrılar ucuzdur. Sıcak bir döngüde kullanılan bir desen için tek bir Regex örneği oluşturun ve onu bir static readonly alanda tutun; binlerce kez çalışıyorsa daha yavaş bir başlangıç karşılığında daha hızlı eşleştirme için RegexOptions.Compiled ekleyin.
Zaman aşımları ve felaket düzeyinde geri izleme
Bazı desenler belirli girdilerde üstel zaman alır. Klasik örnek, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa!"'e karşı ^(a+)+$ gibi iç içe bir niceleyicidir: motor vazgeçmeden önce a'ları iki + arasında bölmenin her yolunu dener. Bir web sunucusunda bir kullanıcıdan gelen tek bir böyle girdi bir CPU çekirdeğini kilitleyebilir (bir "ReDoS" saldırısı). Güvenilmeyen girdiyi ele alan her regex'e bir zaman aşımı verin:
var pattern = new Regex(@"^(\w+\s?)*$", RegexOptions.None, TimeSpan.FromMilliseconds(100));
try
{
bool ok = pattern.IsMatch(userInput);
}
catch (RegexMatchTimeoutException)
{
// treat as invalid input
}
Her statik metodun da bir zaman aşımı alan bir overload'u vardır. .NET 7 ayrıca bazı özellikler (lookaround'lar, geri başvurular) pahasına doğrusal zamanı garanti eden bir motor olan RegexOptions.NonBacktracking'i ekledi.
GeneratedRegex (.NET 7)
.NET 7, bir deseni derleme zamanında sıradan C# koduna çeviren bir source generator ekledi. Başlangıç maliyeti olmadan Compiled'ın hızını alırsınız, üretilen kod IDE'de okunabilir ve trimming ile Native AOT ile çalışır:
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
.NET 7 ve sonrasında derleme zamanında bilinen her desen için önerilen biçim budur.
Yaygın hatalar
- Doğrulamada eksik çapalar.
^...$olmadanIsMatchyalnızca bir eşleşme içeren girdiyi kabul eder. - Desenler için normal string'ler.
"\b"bir kelime sınırı değil bir geri silmedir.@"..."kullanın. - Kaçırılmamış özel karakterler.
.her karakterle eşleşir; desen olarak3.503x50ile de eşleşir.\.ile ya da kullanıcı girdisi içinRegex.Escapeile kaçırın. - Açgözlü niceleyiciler.
<b>bold</b>üzerinde<.*>tüm string'le eşleşir. Tembel.*?'i ya da olumsuzlanmış bir sınıf[^>]*kullanın. - Güvenilmeyen girdide zaman aşımı olmaması. İç içe bir niceleyici bir isteği takılı bırakabilir.
- Yapılandırılmış biçimler için regex. Tırnaklı HTML, JSON ve CSV bir desen değil bir parser gerektirir.
Sıkça Sorulan Sorular
C#'ta regex nasıl kullanılır?
using System.Text.RegularExpressions; ekleyin ve Regex üzerindeki statik metotları çağırın: Regex.IsMatch(input, pattern) bir bool döndürür, Regex.Match ilk eşleşmeyi, Regex.Matches hepsini döndürür, Regex.Replace yerine koyar ve Regex.Split böler. Ters eğik çizgiler regex motoruna değişmeden ulaşsın diye desenleri verbatim string olarak yazın: @"\d+".
C#'ta bir regex eşleşmesinden grup değeri nasıl alınır?
İstediğiniz kısmın etrafına parantez koyun ve match.Groups[1].Value'yu okuyun (gruplar 1'den numaralanır; 0. grup tüm eşleşmedir). Adlandırılmış gruplar daha anlaşılırdır: (?<year>\d{4}), match.Groups["year"].Value ile okunur. Önce match.Success'i kontrol edin, çünkü başarısız bir eşleşmenin grupları null değil boştur.
C#'ta regex ile metin nasıl değiştirilir?
Regex.Replace(input, pattern, replacement) her eşleşmeyi değiştirir. Yerine konan metin gruplara başvurabilir: numaralı bir grup için $1, adlandırılmış biri için ${name}, tüm eşleşme için $0. Bir şablonun ifade edemediği mantık için bir lambda verin: Regex.Replace(text, @"\d+", m => (int.Parse(m.Value) * 2).ToString()).
C#'ta bir regex nasıl harf duyarsız yapılır?
RegexOptions.IgnoreCase verin: Regex.IsMatch(input, "error", RegexOptions.IgnoreCase). Seçenekler | ile birleşir, örneğin RegexOptions.IgnoreCase | RegexOptions.Multiline. Onu desenin içinde (?i) ile de açabilirsiniz.
C#'ta bir e-posta adresi regex ile nasıl doğrulanır?
^[^@\s]+@[^@\s]+\.[^@\s]+$ gibi bir desen bariz yazım hatalarını (eksik @, boşluklar, alan adında nokta olmaması) yakalar ve genellikle bir formun ihtiyaç duyduğu tek şey budur. Bir regex bir adresi gerçekten doğrulayamaz: tam dilbilgisi hiçbir pratik desenin ele alamayacağı biçimlere izin verir ve sözdizimsel olarak geçerli bir adres var olmayabilir. Temel şekli kontrol edin, sonra bir doğrulama e-postası göndererek teyit edin.