IT
OmnvertGörsel • Belge • Ağ

Regex Test Aracı – Düzenli İfade Test Etme ve Açıklama

Regex’i doğrula ve açıkla; yavaş eşleşmelerden kaçın.
Regex’i açıkla
\w: Word char
\b: Word boundary
.: Any char
+: One or more
\.: Literal dot
[]: Character class
{}: Quantifier
Matches
No matches yet.
Test metni
Emails: jane@example.com john.doe@acme.co.uk URLs: https://omnvert.com http://localhost:3000/test
Other developer tools

Açıklama

Regex, tek satıra sıkıştırılmış küçük bir parser'dır; bu yoğunluk yüzünden denemeden koda girmemesi gerekir. Gerçek veriyi yapıştır — dağınık log satırını, gerçek CSV sütununu, geçen hafta patlayan adres kaydını — bayrakları seç ve hangi bölümlerin işaretlendiğine bak. Bozuk desenlerin çoğu egzotik değildir: yanlış yere konmuş bir anchor, gereğinden fazlasını yutan bir quantifier ya da tam da önemli girdiyi dışarıda bırakan bir karakter sınıfı.

Karakter sınıfları desenin sözcük dağarcığıdır. \d tek bir ASCII rakamı, [a-z] tek bir küçük harf, \w ise [A-Za-z0-9_] demektir — alt çizgi dahildir, tire değildir; kebab-case bir slug'da \w+ tam da bu yüzden yarıda kesilir. Başa konan şapka sınıfı tersine çevirir: [^,] virgül dışındaki her karakterdir. Tekrar için quantifier'lar var: ? sıfır veya bir, * sıfır veya daha fazla, + en az bir, {3} tam üç, {2,} en az iki. Sınıfın içinde çoğu metakarakter sıradanlaşır; [.] kaçış karakteri olmadan gerçek noktayı eşler.

Quantifier'lar varsayılan olarak aç gözlüdür ve herkesi bir kez yakalar. <.+> desenini <b>bold</b> üzerinde çalıştırırsan tüm string eşleşir; çünkü .+ alabildiğini alır, sonra kapanış > eşleşsin diye sadece gerektiği kadarını geri verir. Soru işareti ekleyip tembel hale getirirsen — <.+?> — ilk köşeli parantezde durur. Tembel her zaman daha ucuz değildir; sadece geri izlemeyi ters yönden yapar, bazı girdilerde daha çok iş çıkarır.

Anchor'lar karakter değil konum eşler. ^ ve $ girdinin başına ve sonuna sabitler, \b kelime sınırını işaretler; bu yüzden \bcat\b ifadesi concatenate kelimesini atlar. Parantezler aynı anda iki iş yapar: gruplar ve yakalar. Sadece gruplamaya ihtiyacın varsa (?:...) yaz; böylece biri desenin ortasına yeni bir parantez eklediğinde grup numaraların kaymaz. İsimli gruplar çağrı tarafında çok daha okunur: (?<year>\d{4})-(?<month>\d{2}) sana match[1] yerine match.groups.year verir.

Lookahead ve lookbehind, karakter tüketmeden koşul koyar. (?=...) devamında ne olması gerektiğini söyler, (?!...) yasaklar, (?<=...) ve (?<!...) aynısını geriye doğru yapar. Parola kuralı doğal olarak başa sabitlenmiş bir lookahead yığını halinde yazılır: ^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).{10,}$ — tüm koşullar sıfırıncı konumda kontrol edilir, asıl eşleşmeyi .{10,} yapar. Yayına almadan önce kontrol etmen gereken özellik lookbehind: V8 ve Firefox yıllardır destekliyor ama Safari 16.4 ile geldi, yani eski bir iOS cihazda desen çalışma anında değil parse anında SyntaxError atar.

Bayraklar tüm eşleşmenin kurallarını değiştirir. g ilkini değil hepsini döndürür, i büyük/küçük harf farkını yok sayar, m sayesinde ^ ve $ satır sonlarında da eşleşir, s ise noktanın satır sonunu geçmesine izin verir. JavaScript'te g'nin bilinen bir tuzağı var: /g taşıyan bir regex nesnesi lastIndex tutar, dolayısıyla aynı nesne üzerinde .test() çağrısı sırayla true ve false döner. Regex'i döngünün içinde oluştur, lastIndex'i elle sıfırla ya da sadece boolean istiyorsan g'yi kaldır.

İç içe quantifier'lar, desenin yavaşlıktan sekmeyi kilitlemeye geçtiği yerdir. ^(a+)+$ deseni, yirmi beş a ve ardından tek bir X içeren girdide pes etmeden önce üstel sayıda bölünmeyi dener. Gerçek projelerdeki desenler aynı şekli gizler: (\s*\w+)*, ([^,]*,)* veya iki dalı da aynı metni eşleyebilen bir alternation. Tekrarı düzleştir, iç sınıfı dallar çakışmayacak şekilde daraltıcı yaz ve deseni bir request handler'a koymadan önce kasten kötü niyetli bir girdiyle dene. Kullanıcı girdisinden üretilen her desen ayrıca uzunluk limiti ve zaman aşımı hak eder.

JavaScript motoru PCRE değildir; Python veya PHP cevabından kopyalanan desenlerin yarısı düzenleme ister. Atomic group yok, possessive quantifier yok, recursion yok, \A ve \z de yok — onların yerine m bayrağı olmadan ^ ve $ kullan. Unicode'un ayrı bir anahtarı var: \u00e9 sıradan bir BMP kaçışıdır, ama \u{1F600} ve \p{Letter} gibi property escape'ler yalnızca u bayrağıyla parse edilir; u açıkken emoji iki surrogate yarısı değil tek bir birim sayılır.

Bazı işler regex'e uygun biçimde değildir. HTML ve JSON istediği kadar derin iç içe geçebilir, hiçbir düzenli ifade dengeli parantez sayamaz; bu yüzden DOMParser veya JSON.parse ile ayrıştırıp sonucu sorgula. İkinci klasik tuzak e-posta doğrulaması: 6.000 karakterlik desen bile geri dönen adresleri kabul eder, çalışan adresleri reddeder. Tek bir @ ve iki yanında birer parça olduğunu kontrol et, sonra doğrulama bağlantısı gönder. Regex düz metinden veri çıkarmada ve biçim kontrolünde çok iyidir; gerçek bir yapı devreye girdiği anda gerçek bir parser'a geç.

Sık Sorulan Sorular

Hangi bayraklar var?
Global, büyük/küçük harf duyarsız, çok satırlı, dotAll, unicode ve sticky desteklenir.
ReDoS’tan nasıl korunuyorsunuz?
Regex Web Worker’da uzunluk limitleri ve 150 ms zaman aşımıyla çalışır.
Capture group’lar görünüyor mu?
Evet. Eşleşme listesinde indeks ve gruplar yer alır.
Değiştir nasıl çalışır?
Bir replacement metni gir, dönüştürülmüş sonucu gör ve kopyala.
Regex açıklaması ne yapar?
Yaygın token’ları (\d, \w, +, ?, ^, $, [], (), | vb.) kısa Türkçe/İngilizce ipuçlarıyla açıklar.
test() aynı string için neden bir true bir false dönüyor?
g veya y bayrağı taşıyan regex nesnesi lastIndex tutar ve her başarılı eşleşmeden sonra bu değeri ilerletir. İkinci çağrı string'in sonundan itibaren arama yapar ve başarısız olur. Sadece boolean istiyorsan g'yi kaldır, her çağrıdan önce re.lastIndex = 0 yap ya da regex'i döngünün içinde yeniden oluştur.
.* ile .*? arasındaki pratik fark ne?
.* aç gözlüdür: satır sonuna kadar alır ve desenin geri kalanı tutsun diye ancak gerektiği kadar geri verir. .*? tembeldir: sıfır karakterle başlar, birer birer büyür. İki tırnaklı değer içeren bir satırda "(.*)" ilk tırnaktan son tırnağa kadar her şeyi yakalar, "(.*?)" ise sadece ilk değeri.
\d neden Arapça-Hint veya Farsça rakamları eşlemiyor?
JavaScript'te \d tam olarak [0-9] demektir ve hiçbir bayrakla genişlemez; ID ayrıştırırken genelde istediğin de budur. Gerçekten her Unicode ondalık rakamı gerekiyorsa u bayrağını açıp \p{Nd} kullan. Ama bunu bilerek yap: parseInt'e gidecek bir alana ASCII dışı rakam kabul etmek çoğunlukla sorun çıkarır.
m bayrağı mı s bayrağı mı lazım?
İkisi farklı problemleri çözer. m (multiline) ^ ve $ işaretlerini string sınırları yerine her satır sonunda eşletir; log dökümünü satır satır tararken bunu istersin. s (dotAll) ise noktanın satır sonunu da eşlemesini sağlar; tek bir mantıksal kaydın birkaç satıra yayıldığı durumlarda gerekir.
Desenim tarayıcıyı kilitliyor, sebebi ne?
Neredeyse kesinlikle (a+)+ ya da (\w+\s?)+ gibi iç içe veya çakışan quantifier'lardan kaynaklanan catastrophic backtracking. Eşleşmeyen bir girdide motor metni bölmenin üstel sayıda yolunu dener. Bu araç desenleri Web Worker içinde zaman aşımıyla çalıştırdığı için sayfa kilitlenmez, ama aynı desen sunucuda bir CPU çekirdeğini doldurur.
Regex ile iç içe parantezleri veya HTML etiketlerini eşleyebilir miyim?
JavaScript'te hayır. Dengeli iç içelik saymayı gerektirir, düzenli diller sayamaz; PCRE ve .NET bunu recursion ve balancing group ile taklit eder, JavaScript'te ikisi de yoktur. Regex ile düz ve iyi tanımlı bir token yakala, iç içe olan her şeyi DOMParser veya JSON.parse'a bırak.
Non-capturing group neden gerekli?
(?:...) yakalama yuvası ayırmadan gruplama ve alternation sağlar. Böylece desenin ortasına yeni bir parantez eklendiğinde $1, $2 ve match[1] hâlâ aynı şeyi gösterir, ayrıca motor hiç okumayacağın aralıkları kaydetmez. Yakalama grubunu sadece metni geri isteyeceksen kullan.