21 Ocak 2020

Kalıplar ve işaretler

Düzenli ifadeler, metinde arama ve değiştirme yapmak için etkili bir yöntem sağlayan kalıplardır.

JavaScript’te, RegExp nesnesi aracılığıyla kullanılabilirler ve ayrıca string metotlarına entegre edilmişlerdir.

Düzenli İfadeler

Bir düzenli ifade (“regexp” veya sadece “reg”) bir kalıp ve isteğe bağlı işaretlerden oluşur.

Düzenli ifade nesnesi oluşturmak için kullanılabilecek iki sözdizimi vardır.

Uzun olan sözdizimi:

regexp = new RegExp("kalıp", "işaretler");

Ve bölme işareti “/” kullanan kısa olanı:

regexp = /kalıp/; // işaret yok
regexp = /kalıp/gim; // g, m ve i işaretleriyle birlikte (yakında ele alınacak)

Bölme işaretleri /.../ JavaScript’e düzenli bir ifade oluşturduğumuzu söyler. Aynı tırnak işaretlerinin String oluşturduğumuzu söylediği gibi.

Her iki durumda da regexp, RegExp sınıfının bir örneği oluşturulmuş olur.

Bu ikisi arasındaki temel fark, bölme işareti /.../ kullanan modelin kalıba expression eklenmesine izin vermemesidir (${...} kullanan string şablonları gibi). Tamamen statiktirler.

Bölme işaretleri, kod yazarken düzenli ifadeyi önceden bildiğimizde kullanılır – ve bu en yaygın durumdur. new RegExp ise, dinamik olarak oluşturulan bir string’den anında bir regexp oluşturmamız gerektiğinde daha sık kullanılır. Örneğin:

let tag = prompt("Hangi tag'i bulmak istiyorsun?", "h2");

let regexp = new RegExp(`<${tag}>`); //  yukarıdaki prompt'a "h2" cevabı verildiyse,  /<h2>/ ile aynı olur.

İşaretler

Düzenli ifadelerde aramayı etkileyen işaretler olabilir.

JavaScript’te bunlardan sadece 6 tanesi var:

i
Bu işaretle arama, büyük/küçük harfe duyarlı değildir: A ve a arasında fark yoktur (aşağıdaki örneğe bakın).
g
Bu işaretle arama, tüm eşleşenleri arar. Eğer g işareti yoksa, sadece ilk eşleme döndürülür.
m
Çok satırlı mod (Multiline mode of anchors ^ $, flag "m" bölümünde ele alınmıştır).
s
Yeni satır karakteri \n ile eşleşmek için noktaya . izin veren “dotall” modunu etkinleştirir. (Karakter Sınıfları bölümünde ele alınmıştır).
u
Tam unicode desteğini etkinleştirir. Bu işaret, vekil çiftlerin doğru işlenmesini sağlar. Bununla ilgili daha fazla bilgi Unicode: flag "u" and class \p{...} bölümünde.
y
“Yapışkan” mod: metindeki tam pozisyonu arar (Sticky flag "y", searching at position bölümünde ele alınmıştır)
Renkler

Buradan itibaren renk şeması şu şekilde olacak:

  • regexp – red
  • string (aradığımız yer) – blue
  • sonuç – green

Arama: str.match

Daha önce de belirtildiği gibi, düzenli ifadeler string metotlarına entegre edilmiştir.

str.match(regexp) metodu regexp ile str stringindeki tüm eşleşmeleri bulur.

3 çalışma modu vardır:

  1. Düzenli ifadede g işareti varsa, tüm eşleşmelerden oluşan bir dizi döndürür:

    let str = "We will, we will rock you";
    
    alert( str.match(/we/gi) ); // We,we (eşleşen 2 string'den oluşan bir dizi)

    Hem We hem de we’nin bulunduğuna dikkat edin, çünkü i işareti aramayı büyük/küçük harfe duyarsız hale getirir.

  2. Eğer g işareti yoksa, yalnızca ilk eşleşmeyi döndürür. Dönen ifade bir dizi formundadır. İlk eşleşme dizininin 0 indeksinde yer alır ve dizinin bazı ek ayrıntılar sağlayan property’leri vardır:

    let str = "We will, we will rock you";
    
    let result = str.match(/we/i); // g işareti olmadan
    
    alert( result[0] );     // We (ilk eşleşme)
    alert( result.length ); // 1
    
    // Details:
    alert( result.index );  // 0 (eşlemenin string'deki pozisyonu)
    alert( result.input );  // We will, we will rock you (kaynak string)

    Düzenli ifadenin bir kısmı parantez içine alınmışsa dizinin 0 dışında başka indeksleri de olabilir. Bunu, Capturing groups bölümünde ele alacağız.

  3. Son olarak, eşleşme yoksa null döndürülür (g işareti olup olmadığı önemli değildir).

    Bu çok önemli bir nüans. Eşleşme yoksa boş bir dizi almıyoruz, bunun yerine null alıyoruz. Bunu unutmak hatalara neden olabilir, örneğin:

    let matches = "JavaScript".match(/HTML/); // = null
    
    if (!matches.length) { // Error: Cannot read property 'length' of null
      alert("Yukardaki satırda hata var");
    }

    Sonucun her zaman bir dizi olmasını istiyorsak, bunu şu şekilde yazabiliriz:

    let matches = "JavaScript".match(/HTML/) || [];
    
    if (!matches.length) {
      alert("Eşleşme yok"); // şimdi çalışıyor
    }

Yer değiştirme: str.replace

str.replace(regexp, yeni_str) metodu, string str’de regexp kullanılarak bulunan eşleşmeleri yeni_str ile değiştirir (g işareti varsa tüm eşleşmeler, aksi takdirde yalnızca ilk olanı).

Örneğin:

// no flag g
alert( "We will, we will".replace(/we/i, "I") ); // I will, we will

// with flag g
alert( "We will, we will".replace(/we/ig, "I") ); // I will, I will

İkinci argüman, yeni_str bulunan eşlemenin yerine geçen string’dir. Eşleşmenin parçalarını eklemek için özel karakter kombinasyonları kullanabiliriz:

Semboller Değiştirilen yeni_str’de yapılan eylem
$& tüm eşleşmeyi ekler
$` string’in eşleşmeden önce gelen kısmını ekler
$' string’in eşleşmeden sonra gelen kısmını ekler
$n n 1-2 basamaklı bir sayıysa, n. parantezlerin içeriğini ekler, bununla ilgili daha fazla bilgi Capturing groups bölümünde
$<isim> isim adı verilen parantezlerin içeriğini ekler, daha fazlası Capturing groups bölümünde
$$ $ karakterini ekler

$& ile bir örnek::

alert( "I love HTML".replace(/HTML/, "$& and JavaScript") ); // I love HTML and JavaScript

Test: regexp.test

regexp.test(str) metodu en az bir eşleşme arar, eşleşme bulunursa true değerini döndürür, aksi takdirde false değerini döndürür.

let str = "I love JavaScript";
let regexp = /LOVE/i;

alert( regexp.test(str) ); // true

Bu bölümün ilerleyen kısımlarında düzenli ifadeler üzerinde daha fazla çalışacağız, daha fazla örnek üzerinde duracağız ve diğer metotlarla da karşılaşacağız.

Metotlar hakkında tam bilgi Methods of RegExp and String makalesinde verilmiştir.

Özet

  • Düzenli ifade bir kalıp ve isteğe bağlı işaretlerden oluşur: g, i, m, u, s, y.
  • İşaretler ve özel semboller olmadan (daha sonra inceleyeceğiz) düzenli ifadelerle arama bir substring aramasıyla aynıdır.
  • str.match(regexp) metodu eşleşmeleri arar: g işareti varsa tümü, aksi takdirde yalnızca birincisini döner.
  • str.replace(regexp, yeni_str) metodu, regexp kullanılarak bulunan eşleşmeleri yeni_str ile değiştirir: g işareti varsa tümünü, aksi takdirde yalnızca ilkini değiştirir.
  • regexp.test(str) metodu en az bir eşleşme varsa true değerini döndürür, aksi takdirde false değerini döndürür.
Eğitim haritası