Regex Test Aracı
Düzenli ifadeleri güvenle test edin. Eşleştirme, sekmeyi kilitleyen kalıplara karşı zaman sınırlı bir Web Worker içinde çalışır. Türkçe karakter desteği açıklanır.
Başlamak için bir kalıp yazın veya örneği yükleyin.
Özet (TL;DR)
- Eşleştirme ayrı bir Web Worker içinde ve süre sınırıyla çalışır: felaket derecesinde geri izleme yapan bir desen sekmenizi kilitleyemez.
- g bayrağı taşıyan bir RegExp nesnesi lastIndex durumunu saklar, bu yüzden aynı nesneyle art arda test çağırmak sırayla true ve false döndürür.
- Sıfır uzunluklu eşleşmelerde exec döngüsü ilerlemez; lastIndex elle artırılmazsa sonsuz döngüye girer.
- Türkçede \w harflerimizi kapsamaz ve noktalı/noktasız i çifti büyük-küçük harf duyarsız eşleşmeyi bozar.
Felaket derecesinde geri izleme ve neden Worker kullanıyoruz
JavaScript'in düzenli ifade motoru geri izlemeli bir motordur: bir yol tutmadığında geri döner ve alternatifleri dener. İç içe geçmiş niceleyiciler bu alternatiflerin sayısını girdi uzunluğuyla üstel biçimde büyütür. /^(a+)+$/ deseni klasik örnektir. Girdi tamamen a harflerinden oluşup sonunda eşleşmeyi bozan tek bir karakter varsa motor, a'ları gruplara bölmenin tüm olası yollarını denemek zorunda kalır.
const desen = /^(a+)+$/; desen.test('aaaaaaaaaa!'); // 10 a: anlıkdesen.test('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa!'); // 30 a: dakikalar // Neden: (a+)+ ifadesi n adet a'yı gruplara bölmenin 2^(n-1) farklı yolunu dener.// Son karakter eşleşmediği için motor bunların HEPSİNİ tüketmek zorunda kalır. // Çözüm 1: iç içe niceleyiciyi kaldırın/^a+$/.test('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa!'); // anında false // Çözüm 2: belirsizliği ortadan kaldırın/^(?:[^a]|a)+$/ // gruplar örtüşmüyorsa geri izlenecek alternatif de kalmazBu sorun ReDoS adıyla bilinen bir saldırı yüzeyidir. Kullanıcıdan gelen bir metni sunucuda böyle bir desenle eşleştiriyorsanız, saldırgan tek bir istekle işlem sürecini dakikalarca meşgul edebilir. Tarayıcıda ise sonuç daha görünürdür: sekme donar, çünkü eşleştirme ana iş parçacığında senkron çalışır ve durdurulamaz.
Bilgi
lastIndex durumu ve dönüşümlü sonuçlar
JavaScript'te düzenli ifadeler değişmez değer değil, durum taşıyan nesnelerdir. g veya y bayrağı varsa nesne üzerinde lastIndex adında yazılabilir bir alan bulunur ve test ile exec her başarılı eşleşmeden sonra bunu ilerletir. Aynı nesneyi bir döngü içinde tekrar tekrar kullanırsanız sonuçlar sırayla doğru ve yanlış gelir. Bu, üretimde en sık rastlanan düzenli ifade hatalarından biridir.
const re = /ali/g; re.test('ali'); // true (lastIndex artık 3)re.test('ali'); // false (3. konumdan aramaya başladı, lastIndex 0'a döndü)re.test('ali'); // true (döngü baştan başlıyor) // Modül seviyesinde tanımlanan bir desen bu yüzden tehlikelidir:const EPOSTA = /\S+@\S+/g;function gecerliMi(deger) { return EPOSTA.test(deger); // aynı girdiyle her ikinci çağrıda false} // Üç doğru yaklaşım:const EPOSTA_DURUMSUZ = /\S+@\S+/; // 1. g bayrağını kaldırınEPOSTA.lastIndex = 0; // 2. her kullanımdan önce sıfırlayın[...deger.matchAll(/\S+@\S+/g)]; // 3. matchAll kullanın (kopya üzerinde çalışır)Sıfır uzunluklu eşleşme ve sonsuz döngü
Bir desen boş dizeyle eşleşebiliyorsa (a*, \b, (?:) gibi), exec döngüsü ilerlemeyi kendiliğinden yapmaz. Eşleşme uzunluğu sıfır olduğunda lastIndex aynı konumda kalır ve döngü aynı yeri sonsuza kadar okur. Bu aracın eşleştirici kodu tam da bu nedenle matchAll yerine elle yazılmış bir exec döngüsü kullanır: sıfır uzunluklu bir eşleşme gördüğünde lastIndex değerini elle bir artırır.
const re = /a*/g;let m; // SONSUZ DÖNGÜ: 'bbb' içinde her konumda boş eşleşme bulur, ilerlemezwhile ((m = re.exec('bbb')) !== null) { console.log(m.index, JSON.stringify(m[0])); // 0 "" ... 0 "" ... 0 ""} // DOĞRUSU: sıfır uzunluklu eşleşmede konumu elle ilerletinwhile ((m = re.exec('bbb')) !== null) { console.log(m.index, JSON.stringify(m[0])); if (m[0].length === 0) { re.lastIndex++; if (re.lastIndex > 'bbb'.length) break; }}Türkçe karakterler ve noktalı i sorunu
Düzenli ifadelerdeki \w kısayolu ASCII tanımlıdır ve tam olarak [A-Za-z0-9_] kümesine karşılık gelir. Yani ş, ğ, ı, ü, ö, ç harflerinin hiçbiri \w ile eşleşmez. Türkçe metin üzerinde kelime yakalamaya çalışan \w+ deseni "çiçek" kelimesini "i" ve "ek" olarak ikiye böler. Aynı sorun \b kelime sınırı için de geçerlidir, çünkü o da \w tanımına dayanır.
'çiçek bahçesi'.match(/\w+/g);// ['i', 'ek', 'bah', 'esi'] <-- Türkçe harfler sınır sayıldı // Çözüm 1: karakter sınıfını açıkça yazın'çiçek bahçesi'.match(/[a-zçğıöşü]+/gi);// ['çiçek', 'bahçesi'] // Çözüm 2: u bayrağı ile Unicode özellik kaçışı (en temizi)'çiçek bahçesi'.match(/\p{Letter}+/gu);// ['çiçek', 'bahçesi']Asıl sinsi sorun büyük-küçük harf dönüşümündedir. Türkçe alfabede noktalı ve noktasız i ayrı harflerdir: küçük i harfinin büyüğü İ, küçük ı harfinin büyüğü I'dır. Düzenli ifade motoru ise Unicode'un varsayılan eşleme tablosunu kullanır, o tabloda i harfinin büyüğü I'dır. Sonuç olarak i bayrağı Türkçe için yanlış eşleşmeler üretir ve bu hata yalnızca içinde i geçen kelimelerde ortaya çıktığı için testlerde kolayca gözden kaçar.
| Desen | Girdi | Sonuç | Neden |
|---|---|---|---|
| /İSTANBUL/i | istanbul | eşleşmez | Unicode i harfini I ile eşler, İ ile değil |
| /ISTANBUL/i | ıstanbul | eşleşmez | Noktasız ı, I ile eşleşmiyor sayılır |
| /ISTANBUL/i | istanbul | eşleşir | ASCII eşlemesi burada beklenen sonucu verir |
| /[İIiı]stanbul/ | İstanbul | eşleşir | Dört varyantı da açıkça saymak güvenli yoldur |
Uygulama tarafında en güvenilir yaklaşım, karşılaştırmadan önce her iki tarafı da toLocaleLowerCase("tr") ile normalleştirmektir. Arama kutusu gibi kullanıcıya dönük yerlerde bu tek satır, i bayrağının üretebileceği tüm sürprizleri ortadan kaldırır. Düzenli ifadelerin temel söz dizimini ve daha fazla örneği bu sitedeki detaylı rehberde bulabilirsiniz: /blog/regex-rehberi-ve-kullanim-ornekleri
Adlandırılmış gruplar ve d bayrağı
Yakalama gruplarına indis yerine isim vermek, deseni değiştirdiğinizde kırılan match[3] benzeri erişimleri ortadan kaldırır. d bayrağı ise her grubun başlangıç ve bitiş konumlarını indices dizisi içinde verir; vurgulama veya kısmi değiştirme yaparken bu bilgiye ihtiyaç duyarsınız. Bu araç adlandırılmış grupları sonuç tablosunda ayrı sütun olarak gösterir.
const desen = /(?<yil>\d{4})-(?<ay>\d{2})-(?<gun>\d{2})/d;const m = desen.exec('teslim: 2026-07-26'); m.groups.yil; // '2026'm.groups.ay; // '07'm.indices.groups.gun; // [16, 18] <-- d bayrağı olmadan undefined // Değiştirmede de isimle erişilir:'2026-07-26'.replace(desen, '$<gun>.$<ay>.$<yil>');// '26.07.2026'Sıkça Sorulan Sorular
- Girdiğim metin sunucuya gönderiliyor mu?
- Hayır. Desen ve test metni tarayıcınızdan çıkmaz. Eşleştirme sayfayla birlikte gelen bir Web Worker içinde çalışır ve hiçbir ağ isteği yapılmaz, dolayısıyla gerçek günlük kayıtları veya üretim verisiyle rahatça çalışabilirsiniz.
- Deseni çalıştırdım ve zaman aşımı uyarısı aldım, ne yapmalıyım?
- Deseninizde iç içe geçmiş bir niceleyici var demektir; (a+)+ veya (\d+)* gibi yapıları arayın. Genellikle iç grubu tekilleştirerek veya alternatiflerin örtüşmesini engelleyerek çözülür. Aynı desen sunucu tarafında da aynı sorunu yaratır, orada tarayıcı gibi bir koruma olmaz.
- Hangi bayrakları kullanabilirim?
- JavaScript motorunun kabul ettiği tüm bayraklar geçerlidir: d (eşleşme konumları), g (genel), i (büyük-küçük duyarsız), m (çok satırlı), s (nokta yeni satırı da kapsar), u ve v (Unicode modları) ile y (yapışkan). u ve v aynı anda kullanılamaz, çünkü motor bunu söz dizimi hatası sayar.
- Neden yüz binlerce eşleşme yerine sınırlı sonuç görüyorum?
- Sonuç listesi bilinçli olarak sınırlanır. Boşa yakın bir desen büyük bir metinde her konumda eşleşebilir ve bu kadar sonucu ekrana çizmek, düzenli ifade anında bitse bile arayüzü kilitler. Sınır aşıldığında kesme uyarısı gösterilir.
- Buradaki desen Python veya PHP'de aynı çalışır mı?
- Temel söz dizimi büyük ölçüde ortaktır ama farklar vardır. Python lookbehind ifadelerinde sabit uzunluk şartı arar, PCRE atomik gruplar ve possessive niceleyiciler sunar (JavaScript sunmaz), Unicode özellik kaçışlarının yazımı da diller arasında değişebilir. Bu araç JavaScript motorunu kullanır, dolayısıyla sonuçlar tarayıcı ve Node ortamı için kesindir.