Takip et

JavaScript Regular Expressions for Regular People

JavaScript Regular Expressions for Regular People Giriş: Düzenli İfadelerle Tanışın İnternet dünyasında gezinirken, form doldururken, bir

JavaScript Regular Expressions for Regular People

Giriş: Düzenli İfadelerle Tanışın

İnternet dünyasında gezinirken, form doldururken, bir arama yaparken veya basit bir metin düzenlerken, aslında farkında olmadan düzenli ifadelerle (Regular Expressions veya kısaca Regex) karşılaşırsınız. Regex, metinler içindeki belirli kalıpları tanımlamak, bulmak, değiştirmek veya doğrulamak için kullanılan güçlü bir dildir. “Normal insanlar” için ilk başta biraz korkutucu görünebilir; zira karmaşık semboller ve kısaltmalarla dolu bir labirent gibi durur. Ancak endişelenmeyin! Bu makale, JavaScript bağlamında düzenli ifadeleri anlamanız, kullanmanız ve hatta sevmeniz için bir rehber olacak. Adım adım ilerleyerek, bu “sihirli dili” nasıl çözebileceğinizi ve günlük programlama görevlerinizde nasıl kullanabileceğinizi keşfedeceğiz.

Neden Regex’e ihtiyacımız var? Hayal edin ki bir e-posta adresinin geçerli olup olmadığını kontrol etmek istiyorsunuz. Veya bir metin içindeki tüm telefon numaralarını bulup belirli bir formata dönüştürmek istiyorsunuz. Belki de bir URL’den sadece alan adını çekmeniz gerekiyor. Bu tür görevler için, karakter karakter manuel kontrol yapmak hem çok zaman alıcı hem de hataya açık olacaktır. İşte burada Regex devreye girer. Tek bir kalıp (pattern) tanımlayarak, binlerce karakterlik metinler üzerinde saniyeler içinde karmaşık aramalar ve manipülasyonlar yapabilirsiniz. Regex, metin işleme dünyasının İsviçre çakısıdır ve JavaScript ile birleştiğinde, web uygulamalarınızda inanılmaz bir esneklik ve güç sunar.

Regex Temelleri: İlk Adımlar

JavaScript’te bir düzenli ifade oluşturmanın iki temel yolu vardır:

1. Literal Notasyon (Tavsiye Edilen)

Bu yöntem, genellikle daha basit ve daha okunabilir olduğu için tercih edilir. Deseni eğik çizgiler (/) arasına yazarsınız ve ardından isteğe bağlı bayrakları (flags) eklersiniz.

const desen = /kalıp/bayraklar;

Örneğin, “hello” kelimesini arayan ve büyük/küçük harf duyarlı olmayan bir Regex:

const merhabaDeseni = /hello/i; // 'i' bayrağı büyük/küçük harf duyarsızlığı sağlar

2. RegExp Kurucusu

Bu yöntem, deseni veya bayrakları dinamik olarak bir değişkenden oluşturmanız gerektiğinde kullanışlıdır. Deseni ve bayrakları string olarak geçirirsiniz.

const desen = new RegExp("kalıp", "bayraklar");

Aynı “hello” örneği bu şekilde yazılabilir:

const merhabaDeseniDinamik = new RegExp("hello", "i");

RegExp kurucusunu kullanırken, eğer deseninizde ters eğik çizgi (\) gibi özel karakterler varsa, bunları çift ters eğik çizgi (\\) ile kaçırmanız gerektiğini unutmayın, çünkü string içinde ters eğik çizgi zaten bir kaçış karakteridir. Literal notasyonda bu sorun genellikle olmaz, çünkü Regex motoru bunu doğrudan işler.

Yaygın Regex Bayrakları

Bayraklar, düzenli ifadenin davranışını değiştiren tek karakterlik ayarlardır. En sık kullanılanlar şunlardır:

* g (global): Varsayılan olarak, Regex metindeki ilk eşleşmeyi bulduğunda durur. g bayrağı, tüm eşleşmeleri bulmaya devam etmesini sağlar.
* i (case-insensitive): Büyük/küçük harf duyarsız arama yapar. Örneğin, /a/i hem “a” hem de “A” ile eşleşir.
* m (multiline): Çok satırlı mod. ^ ve $ çapalarının sadece tüm metnin başlangıcı/sonu yerine, her satırın başlangıcı/sonu ile eşleşmesini sağlar.
* s (dotAll): . karakterinin normalde yeni satır karakterleri (\n, \r) ile eşleşmemesini sağlar. s bayrağı ile . her karakterle, yeni satır karakterleri dahil, eşleşir.
* u (unicode): Unicode karakter setlerini doğru bir şekilde işlemesini sağlar. Özellikle emoji veya diğer uluslararası karakterlerle çalışırken önemlidir.
* y (sticky): Eşleşmenin sadece lastIndex özelliğinin işaret ettiği konumdan itibaren başlamasını sağlar. g bayrağı ile birlikte kullanılır.

Karakter Sınıfları: Ne Aradığımızı Belirtmek

Regex’in temel yapı taşları, belirli türdeki karakterleri tanımlamamızı sağlayan karakter sınıflarıdır.

1. Harf ve Rakamlar (Literaller)

En basit haliyle, bir karakteri doğrudan yazarak onu arayabilirsiniz:

const arama = /a/; // Sadece 'a' karakterini arar
const sayi = /5/; // Sadece '5' karakterini arar
const kelime = /elma/; // 'elma' kelimesini arar

2. [] Köşeli Parantezler (Karakter Kümeleri)

Köşeli parantezler, içerisindeki herhangi bir karakterle eşleşen bir set tanımlar.

* [abc]: “a”, “b” veya “c” karakterlerinden herhangi biriyle eşleşir.
* [0-9]: Herhangi bir rakamla (0’dan 9’a) eşleşir.
* [a-z]: Herhangi bir küçük harf ile eşleşir.
* [A-Z]: Herhangi bir büyük harf ile eşleşir.
* [a-zA-Z]: Herhangi bir harf ile eşleşir (büyük veya küçük).
* [0-9a-fA-F]: Onaltılık (hexadecimal) rakamlarla eşleşir.

Örnek: Bir metinde “a”, “e” veya “i” harflerini bulalım.

const metin = "Merhaba Dünya";
const sesliler = /[aei]/g;
console.log(metin.match(sesliler)); // Çıktı: ["e", "a", "a", "ü", "a"]

3. [^] Hariç Tutma (Negasyon)

Köşeli parantez içinde ^ karakteri kullanıldığında, bu karakter kümesindeki olmayan herhangi bir karakterle eşleşir.

* [^abc]: “a”, “b” veya “c” dışındaki herhangi bir karakterle eşleşir.
* [^0-9]: Herhangi bir rakam dışındaki karakterle eşleşir.

Örnek: Bir metinde rakam olmayan tüm karakterleri bulalım.

const metin = "Fiyat: 123 TL";
const rakamDisi = /[^0-9]/g;
console.log(metin.match(rakamDisi)); // Çıktı: ["F", "i", "y", "a", "t", ":", " ", " ", "T", "L"]

4. Kısayol Karakter Sınıfları

Bu kısayollar, sık kullanılan karakter kümelerini daha kısa ve okunabilir bir şekilde ifade etmenizi sağlar:

* \d: Herhangi bir rakamla eşleşir (digit). [0-9] ile aynıdır.
* \D: Rakam olmayan herhangi bir karakterle eşleşir. [^0-9] ile aynıdır.
* \w: Herhangi bir kelime karakteriyle eşleşir (word character). Harfler, rakamlar ve alt çizgi (_). [a-zA-Z0-9_] ile aynıdır.
* \W: Kelime karakteri olmayan herhangi bir karakterle eşleşir. [^a-zA-Z0-9_] ile aynıdır.
* \s: Herhangi bir boşluk karakteriyle eşleşir (whitespace). Boşluk, sekme (\t), yeni satır (\n), satır başı (\r) vb.
* \S: Boşluk karakteri olmayan herhangi bir karakterle eşleşir.
* .: Yeni satır karakterleri (\n, \r) hariç herhangi bir karakterle eşleşir. s (dotAll) bayrağı ile yeni satır karakterleri de dahil tüm karakterlerle eşleşir.

Örnek: Bir metindeki tüm kelimeleri bulalım.

const metin = "Merhaba, dünya! Nasılsın?";
const kelimeler = /\w+/g; // '+' niceleyicisi ile birlikte kullanılır, bir veya daha fazla kelime karakteri
console.log(metin.match(kelimeler)); // Çıktı: ["Merhaba", "dünya", "Nasılsın"]

Niceleyiciler (Quantifiers): Kaç Kere?

Niceleyiciler, bir karakterin, karakter sınıfının veya grubun kaç kez tekrar edebileceğini belirtir.

(Sıfır veya Daha Fazla): Önceki öğenin sıfır veya daha fazla tekrarıyla eşleşir.

/a*/ // Sıfır veya daha fazla 'a' ile eşleşir ("" veya "a" veya "aaa")

* + (Bir veya Daha Fazla): Önceki öğenin bir veya daha fazla tekrarıyla eşleşir.

/a+/ // Bir veya daha fazla 'a' ile eşleşir ("a" veya "aaa", ama "" ile eşleşmez)

* ? (Sıfır veya Bir): Önceki öğenin sıfır veya bir tekrarıyla eşleşir (isteğe bağlı).

/colou?r/ // "color" veya "colour" ile eşleşir

* {n} (Tam Olarak n Kez): Önceki öğenin tam olarak n kez tekrarıyla eşleşir.

/\d{3}/ // Tam olarak 3 rakamla eşleşir ("123")

* {n,} (n veya Daha Fazla): Önceki öğenin n veya daha fazla tekrarıyla eşleşir.

/\d{3,}/ // 3 veya daha fazla rakamla eşleşir ("123", "12345")

* {n,m} (n ile m Arası): Önceki öğenin en az n, en fazla m kez tekrarıyla eşleşir.

/\d{3,5}/ // 3, 4 veya 5 rakamla eşleşir ("123", "1234", "12345")

Açgözlü (Greedy) ve Tembel (Lazy) Niceleyiciler

Varsayılan olarak, niceleyiciler “açgözlüdür” (greedy). Bu, mümkün olan en uzun eşleşmeyi bulmaya çalıştıkları anlamına gelir. Niceleyicinin sonuna ? ekleyerek onu “tembel” (lazy) yapabilirsiniz, bu da mümkün olan en kısa eşleşmeyi bulmaya çalışacağı anlamına gelir.

Örnek: HTML etiketlerini eşleştirme.

const metin = "
Merhaba
Dünya"; const greedyDesen = //g; // Açgözlü: İlk '' arasındaki her şeyi eşleştirir console.log(metin.match(greedyDesen)); // Çıktı: ["
Merhaba
Dünya"] - Tüm stringi eşleştirdi! const lazyDesen = //g; // Tembel: Her '' arasındaki her şeyi eşleştirir console.log(metin.match(lazyDesen)); // Çıktı: ["
", "
", "", ""] - İstediğimiz gibi ayrı etiketleri eşleştirdi.

Çapalar (Anchors): Konum Belirleme

Çapalar, bir eşleşmenin metin içinde belirli bir konumda gerçekleşmesini sağlar.

* ^ (Metin/Satır Başı): Eşleşmenin metnin veya m bayrağı kullanıldığında her satırın başında gerçekleşmesini sağlar.

/^Merhaba/ // "Merhaba Dünya" ile eşleşir, ama "Dünya Merhaba" ile eşleşmez

* $ (Metin/Satır Sonu): Eşleşmenin metnin veya m bayrağı kullanıldığında her satırın sonunda gerçekleşmesini sağlar.

/Dünya$/ // "Merhaba Dünya" ile eşleşir, ama "Dünya Merhaba" ile eşleşmez

* \b (Kelime Sınırı): Bir kelime karakteri ile kelime karakteri olmayan bir karakter (veya metnin başı/sonu) arasındaki sınırı eşleştirir.

/\bcat\b/ // "cat" kelimesiyle eşleşir, ama "catalog" veya "tomcat" ile eşleşmez

* \B (Kelime Sınırı Değil): \b‘nin tam tersi; bir kelime sınırı olmayan bir konumu eşleştirir.

/\Bcat\B/ // "tomcat" içindeki "cat" ile eşleşir, ama "cat" veya "catalog" ile eşleşmez

Örnek: Bir metinde sadece tam “elma” kelimesini bulalım.

const metin = "Elma yemek güzeldir. Elmalı turta severim. Elma";
const tamElma = /\belma\b/gi; // 'i' büyük/küçük harf duyarsızlığı için
console.log(metin.match(tamElma)); // Çıktı: ["Elma", "Elma"]

Gruplama ve Yakalama: Bölümlere Ayırma

Parantezler () Regex’te birden fazla amaç için kullanılır:

1. Yakalayıcı Gruplar (Capturing Groups)

Parantezler içindeki bir deseni tek bir birim olarak gruplar ve bu grubun eşleşen kısmını daha sonra erişmek üzere yakalar.

const tarih = /(\d{2})\/(\d{2})\/(\d{4})/; // Gün, ay ve yıl için 3 yakalayıcı grup
const metin = "Bugünün tarihi 25/10/2023.";
const eslesme = metin.match(tarih);
console.log(eslesme);
/*
Çıktı (yaklaşık):
[
  "25/10/2023", // Tam eşleşme
  "25",         // 1. yakalayıcı grup
  "10",         // 2. yakalayıcı grup
  "2023",       // 3. yakalayıcı grup
  index: 16,
  input: "Bugünün tarihi 25/10/2023.",
  groups: undefined
]
*/

Gördüğünüz gibi, match metodu tam eşleşmenin yanı sıra yakalayıcı grupların eşleşmelerini de bir dizi olarak döndürdü.

2. Geri Referanslar (Backreferences)

\n sözdizimi ile daha önce yakalanmış bir gruba referans verebilirsiniz. n, grubun sırasıdır (1’den başlar).

Örnek: Tekrar eden kelimeleri bulalım.

const metin = "Bu bir test test cümlesidir. Güzel güzel hava.";
const tekrarEdenKelime = /\b(\w+)\s+\1\b/g; // \1 ilk yakalayıcı gruba (\w+) referans verir
console.log(metin.match(tekrarEdenKelime)); // Çıktı: ["test test", "güzel güzel"]

3. Yakalayıcı Olmayan Gruplar (Non-Capturing Groups)

(?:\...) sözdizimi ile bir deseni gruplarsınız, ancak bu grubun eşleşmesini yakalamazsınız. Bu, performansı artırabilir ve match dizisinin daha temiz olmasını sağlayabilir.

const desen = /(?:http|https):\/\/(www\.)?(\w+\.\w+)/; // http/https grubu yakalanmaz
const metin = "Web sitemiz https://www.example.com adresinde.";
const eslesme = metin.match(desen);
console.log(eslesme);
/*
Çıktı (yaklaşık):
[
  "https://www.example.com",
  "www.",         // 1. yakalayıcı grup (www.)
  "example.com",  // 2. yakalayıcı grup (alan adı)
  // ...
]
*/
// Eğer (http|https) yakalayıcı grup olsaydı, "https" de dizide olurdu.

4. İleriye ve Geriye Bakışlar (Lookaheads & Lookbehinds)

Bunlar daha gelişmiş gruplama teknikleridir ve belirli bir deseni eşleştirmeden önce veya sonra belirli bir koşulun olup olmadığını kontrol etmenizi sağlar. Deseni eşleşmeye dahil etmezler.

* Pozitif İleriye Bakış (?=...): Yalnızca ... deseni takip ediyorsa eşleşir.

/\w+(?=\sTL)/g; // " TL" ile biten bir kelimeyi eşleştirir, ama " TL" kısmını eşleşmeye dahil etmez
    const metin = "Fiyat 150 TL. İndirim 20 TL.";
    console.log(metin.match(/\d+(?=\sTL)/g)); // Çıktı: ["150", "20"]

* Negatif İleriye Bakış (?!...): Yalnızca ... deseni takip etmiyorsa eşleşir.

/\b(?!admin)\w+\b/g; // "admin" olmayan kelimeleri eşleştirir
    const metin = "admin user guest";
    console.log(metin.match(/\b(?!admin)\w+\b/g)); // Çıktı: ["user", "guest"]

* Pozitif Geriye Bakış (?<=...): Yalnızca ... deseni ile başlıyorsa eşleşir (ES2018 ile geldi).

/(?<=\$)\d+/g; // "$" karakterinden sonra gelen sayıları eşleştirir, ama "$" karakterini eşleşmeye dahil etmez
    const metin = "Ürün fiyatı $100 ve $250.";
    console.log(metin.match(/(?<=\$)\d+/g)); // Çıktı: ["100", "250"]

* Negatif Geriye Bakış (?: Yalnızca ... deseni ile başlamıyorsa eşleşir (ES2018 ile geldi).

/(?

Alternasyon ve Kaçış Karakterleri

1. | (VEYA Operatörü)

Dikey çizgi, iki veya daha fazla desen arasında bir "VEYA" ilişkisi kurar. Bir desenin diğerinden biriyle eşleşmesini istediğinizde kullanışlıdır.

/(elma|armut|muz)/ // "elma", "armut" veya "muz" ile eşleşir

Örnek: Bir metindeki renk isimlerini bulalım.

const metin = "Kırmızı araba, mavi gökyüzü, yeşil çimen.";
const renkler = /(kırmızı|mavi|yeşil)/gi;
console.log(metin.match(renkler)); // Çıktı: ["Kırmızı", "mavi", "yeşil"]

2. Özel Karakterlerden Kaçış (\)

Regex'in bazı karakterleri özel anlamlara sahiptir (., *, +, ?, [, ], (, ), {, }, ^, $, |, \, /). Eğer bu karakterleri literal olarak (özel anlamları olmadan) eşleştirmek isterseniz, önüne bir ters eğik çizgi (\) koyarak onları kaçırmanız gerekir.

Örnek: Bir metinde . (nokta) karakterini aramak.

const metin = "Bu bir cümle sonu.";
const nokta = /\./g; // Noktayı literal olarak arar
console.log(metin.match(nokta)); // Çıktı: ["."]

// Eğer kaçmasaydık:
const herKarakter = /./g; // Yeni satır hariç her karakterle eşleşir
console.log(metin.match(herKarakter)); // Çıktı: ["B", "u", " ", "b", "i", "r", " ", "c", "ü", "m", "l", "e", " ", "s", "o", "n", "u"]

JavaScript String Metotları ve Regex

JavaScript'in String prototipi, düzenli ifadelerle çalışmak için birkaç kullanışlı metoda sahiptir.

1. string.match(regex)

Bir string'i bir Regex deseniyle eşleştirmeye çalışır.
* g bayrağı yoksa: İlk eşleşmeyi içeren bir dizi döndürür (yakalayıcı gruplar dahil). Eşleşme yoksa null döndürür.
* g bayrağı varsa: Tüm eşleşmeleri içeren bir dizi döndürür. Yakalayıcı grupları döndürmez, sadece tam eşleşmeleri. Eşleşme yoksa null döndürür.

const metin = "Merhaba dünya, merhaba JavaScript!";
const desen = /merhaba/gi;
console.log(metin.match(desen)); // Çıktı: ["Merhaba", "merhaba"]

2. string.matchAll(regex) (ES2020)

g bayrağı zorunludur. Eşleşmelerin bir yineleyicisini (iterator) döndürür. Her eşleşme, match() metodunun g bayrağı olmadan döndürdüğü dizi formatındadır (tam eşleşme ve yakalayıcı gruplar).

const metin = "Merhaba dünya, merhaba JavaScript!";
const desen = /merhaba (\w+)/gi; // Yakalayıcı grup ile
const eslesmeler = metin.matchAll(desen);

for (const eslesme of eslesmeler) {
  console.log(eslesme);
  /*
  Çıktı (her iterasyonda):
  ["Merhaba dünya", "dünya", index: 0, input: "...", groups: undefined]
  ["merhaba JavaScript", "JavaScript", index: 15, input: "...", groups: undefined]
  */
}

3. string.search(regex)

Bir string içinde Regex deseniyle eşleşen ilk alt dizinin başlangıç indeksini döndürür. Eşleşme bulunamazsa -1 döndürür. g bayrağı bu metot için bir fark yaratmaz, her zaman ilk eşleşmeyi bulur.

const metin = "Bugün hava güzel.";
console.log(metin.search(/hava/)); // Çıktı: 7
console.log(metin.search(/yağmur/)); // Çıktı: -1

4. string.replace(regex, replacement)

Regex deseniyle eşleşen alt dizileri belirtilen replacement ile değiştirir.
* g bayrağı yoksa: Sadece ilk eşleşmeyi değiştirir.
* g bayrağı varsa: Tüm eşleşmeleri değiştirir.
replacement bir string veya bir fonksiyon olabilir. String olarak kullanıldığında, $1, $2 gibi ifadelerle yakalayıcı gruplara referans verebilirsiniz.

const metin = "Merhaba dünya, merhaba JavaScript!";
// İlk eşleşmeyi değiştir
console.log(metin.replace(/merhaba/i, "Selam")); // Çıktı: "Selam dünya, merhaba JavaScript!"

// Tüm eşleşmeleri değiştir
console.log(metin.replace(/merhaba/gi, "Selam")); // Çıktı: "Selam dünya, Selam JavaScript!"

// Yakalayıcı grupları kullanarak format değiştirme
const tarih = "25-10-2023";
const tarihDeseni = /(\d{2})-(\d{2})-(\d{4})/;
console.log(tarih.replace(tarihDeseni, "$3/$2/$1")); // Çıktı: "2023/10/25"

// Fonksiyon ile değiştirme
const metin2 = "apple orange banana";
console.log(metin2.replace(/\b(\w+)\b/g, (match) => match.toUpperCase())); // Çıktı: "APPLE ORANGE BANANA"

5. string.split(regex)

Bir string'i Regex deseniyle belirlenen ayraçlara göre bir diziye böler.

const metin = "elma,armut;muz portakal";
console.log(metin.split(/[,; ]/)); // Virgül, noktalı virgül veya boşluğa göre ayırır
// Çıktı: ["elma", "armut", "muz", "portakal"]

JavaScript RegExp Metotları

RegExp nesnesinin kendisi de Regex ile çalışmak için metotlara sahiptir.

1. regexp.test(string)

Bir string'in Regex deseniyle eşleşip eşleşmediğini kontrol eder. true veya false döndürür. Sadece bir eşleşmenin varlığını kontrol etmek için en verimli yoldur.

const desen = /\d{3}/;
console.log(desen.test("abc123def")); // Çıktı: true
console.log(desen.test("abcdef"));   // Çıktı: false

2. regexp.exec(string)

string.match() metoduna benzer, ancak g bayrağı ile kullanıldığında farklı davranır.
* İlk eşleşmeyi bulan bir dizi döndürür (yakalayıcı gruplar dahil). Eşleşme yoksa null döndürür.
* g bayrağı varsa, her çağrıldığında bir sonraki eşleşmeyi bulur ve regexp.lastIndex özelliğini günceller. Bu, bir döngü içinde tüm eşleşmeler üzerinde yineleme yapmak için kullanışlıdır.

const metin = "Kedi ve köpek, kedi miyavlar.";
const desen = /kedi/g; // 'g' bayrağı ile

let eslesme;
while ((eslesme = desen.exec(metin)) !== null) {
  console.log(Eşleşme: ${eslesme[0]}, Başlangıç İndeksi: ${eslesme.index});
  console.log(Sonraki arama indeksi: ${desen.lastIndex});
}
/*
Çıktı:
Eşleşme: Kedi, Başlangıç İndeksi: 0
Sonraki arama indeksi: 4
Eşleşme: kedi, Başlangıç İndeksi: 13
Sonraki arama indeksi: 17
*/

Pratik Uygulamalar ve Örnekler

Artık temel bilgileri edindiğimize göre, Regex'i gerçek dünya senaryolarında nasıl kullanabileceğimizi görelim.

1. E-posta Doğrulama

Tamamen kusursuz bir e-posta Regex'i yazmak oldukça karmaşıktır, ancak çoğu durum için yeterli olacak basit bir tanım:

const emailRegex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;

console.log(emailRegex.test("test@example.com"));     // true
console.log(emailRegex.test("john.doe123@mail.co.uk")); // true
console.log(emailRegex.test("invalid-email"));         // false
console.log(emailRegex.test("user@.com"));             // false (alan adından önce nokta olamaz)

* ^: String'in başlangıcı.
* [a-zA-Z0-9._%+-]+: Kullanıcı adı kısmı. Harfler, rakamlar, nokta, alt çizgi, yüzde, artı veya eksi işaretlerinden bir veya daha fazlası.
* @: @ işareti.
* [a-zA-Z0-9.-]+: Alan adı kısmı. Harfler, rakamlar, nokta veya eksi işaretlerinden bir veya daha fazlası.
* \.: Nokta (kaçış karakteriyle).
* [a-zA-Z]{2,}: Top level domain (TLD) kısmı. En az iki harften oluşur.
* $: String'in sonu.

2. Telefon Numarası Doğrulama (Örnek: Türkiye)

Türkiye'deki telefon numaraları genellikle (XXX) XXX XX XX veya XXX XXX XX XX formatındadır.

const telefonNoRegex = /^(?:(?:\+90|0)?\s?|\(0?)?(\d{3})[)\s.-]?(\d{3})[)\s.-]?(\d{2})[)\s.-]?(\d{2})$/;

console.log(telefonNoRegex.test("0532 123 45 67"));   // true
console.log(telefonNoRegex.test("(532) 123 45 67")); // true
console.log(telefonNoRegex.test("+90 532 123 45 67")); // true
console.log(telefonNoRegex.test("532-123-45-67"));   // true
console.log(telefonNoRegex.test("1234567890"));      // false (eksik basamak)

Bu Regex, farklı formatlardaki Türkiye telefon numaralarını yakalamaya çalışır. (?:...) yakalayıcı olmayan gruplar ve ? isteğe bağlı niceleyiciler kullanılarak esneklik sağlanmıştır.

3. URL Eşleştirme ve Bileşenlerini Ayırma

Bir URL'den protokol, alan adı ve yolu ayıklayalım.

const url = "https://www.example.com:8080/path/to/page?query=test#hash";
const urlRegex = /^(https?):\/\/(www\.)?([\w.-]+)(:\d+)?(\/[\w/.-])?(\?\S)?(#\S*)?$/;

const eslesme = url.match(urlRegex);

if (eslesme) {
  console.log("Protokol:", eslesme[1]); // https
  console.log("Subdomain (www.):", eslesme[2]); // www.
  console.log("Alan Adı:", eslesme[3]); // example.com
  console.log("Port:", eslesme[4]); // :8080
  console.log("Yol:", eslesme[5]); // /path/to/page
  console.log("Sorgu Parametreleri:", eslesme[6]); // ?query=test
  console.log("Hash:", eslesme[7]); // #hash
}

Bu örnek, yakalayıcı grupların karmaşık verileri parçalamak için ne kadar güçlü olduğunu gösterir.

4. Tarih Formatı Çıkarma ve Dönüştürme

GG-AA-YYYY formatındaki bir tarihi YYYY/AA/GG formatına dönüştürelim.

const tarihMetin = "Bugünün tarihi 25-10-2023 ve yarın 26-10-2023.";
const tarihDesen = /(\d{2})-(\d{2})-(\d{4})/g;

const yeniTarihMetin = tarihMetin.replace(tarihDesen, "$3/$2/$1");
console.log(yeniTarihMetin); // Çıktı: "Bugünün tarihi 2023/10/25 ve yarın 2023/10/26."

5. Şifre Gücü Kontrolü

Basit bir şifre kontrolü: En az 8 karakter, en az bir büyük harf, bir küçük harf ve bir rakam içermeli.

const password = "Password123";
const passwordRegex = /^(?=.[a-z])(?=.[A-Z])(?=.*\d)[a-zA-Z\d]{8,}$/;

console.log(passwordRegex.test(password));      // true
console.log(passwordRegex.test("password"));    // false (büyük harf yok)
console.log(passwordRegex.test("PASSWORD123")); // false (küçük harf yok)
console.log(passwordRegex.test("Pass1"));       // false (8 karakterden az)

Burada üç adet pozitif ileriye bakış ((?=...)) kullandık. Her biri, şifrenin tamamı eşleşmeden önce belirli bir koşulu kontrol eder. [a-zA-Z\d]{8,}$ kısmı ise şifrenin en az 8 karakter uzunluğunda olmasını ve sadece harf veya rakam içermesini sağlar.

6. Metin İçindeki Belirli Kelimeleri Değiştirme/Sansürleme

Bir metindeki küfürlü kelimeleri sansürleyelim.

const metin = "Bu bir kötü kelime ve başka bir kötü kelime içeriyor.";
const sansurDesen = /(kötü kelime|başka bir kötü kelime)/gi; // Sansürlenecek kelimeler

const sansurluMetin = metin.replace(sansurDesen, "*");
console.log(sansurluMetin); // Çıktı: "Bu bir  ve  içeriyor."

İpuçları ve En İyi Uygulamalar

Regex öğrenme ve kullanma sürecinizi kolaylaştıracak bazı ipuçları:

1. Adım Adım Başlayın: Karmaşık bir desen oluşturmanız gerektiğinde, tümünü birden yazmaya çalışmayın. Küçük parçalar halinde başlayın ve her parçanın doğru çalıştığından emin olarak yavaş yavaş eklemeler yapın.
2. Online Araçlar Kullanın: Regex öğrenmek ve hata ayıklamak için harika online araçlar vardır.
* [regex101.com](https://regex101.com/): Deseninizi yazarken her bir parçayı ayrı ayrı açıklar, örnek metin üzerinde eşleşmeleri anında gösterir ve farklı diller için kod parçacıkları sunar.
* [regexr.com](https://regexr.com/): Benzer işlevsellik sunar, ayrıca yaygın desenler için bir kütüphane içerir.
Bu araçlar, Regex'i görsel olarak anlamanıza ve hataları hızla bulmanıza yardımcı olur.
3. Test Edin, Test Edin, Test Edin: Yazdığınız Regex'i çeşitli geçerli ve geçersiz girişlerle test ettiğinizden emin olun. Beklenmeyen kenar durumları (edge cases) her zaman ortaya çıkabilir.
4. Performans Konuları: Çok karmaşık veya aşırı genelleştirilmiş Regex'ler (örneğin, . gibi açgözlü niceleyicilerin aşırı kullanımı) "Regex deneme yanılma" (catastrophic backtracking) sorununa yol açabilir ve uygulamanızı yavaşlatabilir veya çökertedebilir. Mümkün olduğunca spesifik olun ve tembel niceleyicileri (?, +?) ne zaman kullanacağınızı bilin.
5. Okunabilirlik İçin Yorumlar: JavaScript Regex'lerinin içine doğrudan yorum ekleyemeseniz de, kodunuzda Regex'in ne anlama geldiğini açıklayan yorumlar bırakın. Özellikle karmaşık desenler için bu, gelecekte sizin veya başkalarının kodu anlamasına yardımcı olacaktır.
6. Kütüphaneler: Bazen çok karmaşık Regex görevleri için özel kütüphaneler kullanmak daha iyi bir çözüm olabilir. Ancak çoğu zaman, yerleşik JavaScript Regex yetenekleri yeterlidir.

Sonuç

"JavaScript Regular Expressions for Regular People" başlıklı bu makalede, düzenli ifadelerin temelden ileri seviyeye kadar birçok yönünü ele aldık. Regex'in ilk başta karmaşık semboller yığını gibi görünse de, adım adım öğrenildiğinde ve pratik uygulamalarla pekiştirildiğinde ne kadar güçlü ve kullanışlı bir araç olduğunu gördük. Karakter sınıflarından niceleyicilere, çapalardan gruplamaya ve JavaScript'in String ve RegExp metotlarına kadar birçok konuyu örneklerle inceledik.

Unutmayın ki Regex, bir kere öğrenip bırakılacak bir konu değildir; sürekli pratik ve deneme gerektirir. Karşılaştığınız her yeni metin işleme probleminde Regex kullanmayı düşünmek, bu dili içselleştirmenize yardımcı olacaktır. Online araçları aktif olarak kullanarak ve bol bol deneme yaparak, kısa sürede bir Regex ustasına dönüşebilirsiniz. Metinleri arama, doğrulama, çıkarma ve değiştirme yetenekleriniz programlama becerilerinizi bambaşka bir seviyeye taşıyacaktır. Korkmayın, deneyin ve Regex'in gücünü keşfedin!

Yorumlar
İçeriği beğendiniz mi? Bir tartışma başlatın veya görüşlerinizi paylaşın.
Yorum Yaz

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

Gönder

E-posta Bülteni
Yazılım Topluluğuna Katılın
En son güncellemeleri, yaratıcı ipuçlarını ve özel kaynakları doğrudan e-posta kutunuza alın. Tasarım ve inovasyonun geleceğini birlikte keşfedelim.
Mobil sürümden çık