13 Mart 2024

Nicelik Belirteçleri +, *, ? and {n}

Diyelim ki +7(903)-123-45-67 şeklinde bir karakter dizimiz var ve biz bu dizideki sayıların tamamını bulmak istiyoruz. Ama öncekinden farklı olarak, tek bir sayıyla değil, bütün sayılarla ilgileniyoruz: 7, 903, 123, 45, 67.

Sayı, bir veya daha fazla rakamdan oluşan bir dizidir \d. Kaç tanesine sahip olduğumuzu işaretlemek için bir nicelik belirteci ekleyebiliriz.

Nicelik {n}

En basit nicelik belirteci, süslü parantezler içindeki bir sayıdır: {n}.

Bir karaktere (ya da bir karakter sınıfına, veya [...] kümesine vb.) nicelik belirteci eklendiğinde, bize kaç tanesine sahip olduğumuzu belirtir.

Birkaç gelişmiş formu var, örneklere bakalım:

Tam sayım: {5}

\d{5}, \d\d\d\d\d ile benzerdir. İkiside tam olarak 5 adet rakamı belirtir.

Aşağıdaki örnekte 5 basamaklı sayı aranır:

alert( "12345 yaşındayım".match(/\d{5}/) ); //  "12345"

Daha uzun sayıları hariç tutmak için \b kullanabiliriz: \b\d{5}\b.

{3,5}, 3 ila 5 aralığında eşleştirir

3 ila 5 basamaklı sayıları bulmak için sınırları süslü parantezlerin içinde belirtebiliriz: \d{3,5}

alert( "12 yaşında değilim, 1234 yaşındayım.".match(/\d{3,5}/) ); // "1234"

Üst sınırı kaldırabiliriz.

\d{3,}, 3 veya daha fazla basamaklı sayıları arar:

alert( "12 yaşında değilim, 345678 yaşındayım".match(/\d{3,}/) ); // "345678"

Şimdi +7(903)-123-45-67 değerine dönelim.

Sayı, arka arkaya bir veya daha fazla rakamdan oluşan bir dizidir. Yani düzenli ifade (regexp) şu şekilde olacaktır, \d{1,}:

let str = "+7(903)-123-45-67";

let numbers = str.match(/\d{1,}/g);

alert(numbers); // 7,903,123,45,67

Kısaltmalar

Çok kullanılan nicelik belirteçlerinin kısaltmaları mevcuttur:

+

“bir veya daha fazlası” anlamına gelir, {1,} ifadesine benzerdir.

Örneğin, \d+ sayıları aramak içindir:

let str = "+7(903)-123-45-67";

alert( str.match(/\d+/g) ); // 7,903,123,45,67
?

“sıfır ya da bir” anlamına gelir, {0,1} ifadesine benzerdir. Başka bir deyişle, isteğe bağlı hale getirir.

Örneğin, ou?r kalıbı, ilk önce o için, ardından u (sıfır veya bir adet) için, ve daha sonrasında r için arama yapar.

Yani, colou?r, hem color hem de colour öğelerini bulur:

let str = "Should I write color or colour?";

alert( str.match(/colou?r/g) ); // color, colour
*

“Sıfır veya daha fazlası” anlamına gelir, {0,} ile benzerdir. Yani bir karakter kendini tekrar edebilir veya hiç olmayabilir:

Örnek olarak, \d0*, bir sayı ve ardından onu takip eden sıfırları arar (çok sayıda sıfır olabilir ya da hiç olmayabilir):

alert( "100 10 1".match(/\d0*/g) ); // 100, 10, 1

Bunu + (bir veya daha fazlası) ile karşılaştıralım:

alert( "100 10 1".match(/\d0+/g) ); // 100, 10
// 1 eşleşmedi, çünkü 0+ ifadesi en az bir sıfır varlığını gerektirir.

Daha Fazla Örnek

Nicelik belirteçleri sıklıkla kullanılır. Karmaşık düzenli ifade kalıplarının (regexp pattern) “yapı taşı” olarak kullanılırlar. Bu yüzden daha fazla örnek görelim.

Ondalık kesirler için düzenli ifadeler (regexp) (kayan noktalı bir sayı): \d+\.\d+

alert( "0 1 12.345 7890".match(/\d+\.\d+/g) ); // 12.345

“Nitelik barındırmayan HTML açılış etiketleri” için bir düzenli ifade (regexp),<span> veya <p> gibi.

  1. En basit olanı: /<[a-z]+>/i

    alert( "<body> ... </body>".match(/<[a-z]+>/gi) ); // <body>

    Bu düzenli ifade (regexp), ilk olarak '<' için, ardından bir veya daha fazla Latin harfi için ve daha sonrasında '>' için bir arama yapar.

  2. Gelişmiş hali: /<[a-z][a-z0-9]*>/i

    Standarda göre HTML etiket isimleri <h1> gibi ilk karakter dışında herhangi bir pozisyonda bir rakam içerebilir.

    alert( "<h1>Hi!</h1>".match(/<[a-z][a-z0-9]*>/gi) ); // <h1>

“Nitelik barındırmayan HTML açılış ve kapanış etiketleri” için düzenli ifade (regexp): /<\/?[a-z][a-z0-9]*>/i

Kalıbın başında /? ile isteğe bağlı bir eğik çizgi (slash) belirttim. Ters eğik çizgiyle (backslash) bundan kurtuldum, aksi takdirde JavaScript bunun, düzenli ifade kalıbının sonu olduğunu düşünecekti.

alert( "<h1>Merhaba!</h1>".match(/<\/?[a-z][a-z0-9]*>/gi) ); // <h1>, </h1>
Bir düzenli ifadeyi daha tutarlı/kesin hale getirmek için genellikle onu daha karmaşık hale getirmek gerekir

Bu örneklerde genel bir kural görebiliriz: düzenli ifade ne kadar tutarlı/kesin ise o kadar uzun ve karmaşıktır.

Örneğin, HTML etiketleri için daha basit bir ifade kullanabiliriz: <\w+>. Ancak HTML, etiket isimleri için kısıtlamalara sahip olduğundan dolayı, <[a-z][a-z0-9]*> daha güvenilirdir.

<\w+> kalıbını kullanabilir miyiz yoksa <[a-z][a-z0-9]*> kalıbını mı kullanmamız gerekir?

Gerçek hayatta ikiside kabul edilebilir. “Ekstra” eşleşmelere ne kadar tahammül edebileceğimize ya da bunları başka yollarla sonuçtan çıkarmanın zor olup olmadığına bağlıdır.

Görevler

önem: 5

Üç noktayı bulmak için bir düzenli ifade oluşturun: Art arda 3 nokta (veya daha fazlası?).

Kontrol et:

let regexp = /duzenli ifaden/g;
alert( "Merhaba!... Nasıl gidiyor?.....".match(regexp) ); // ..., .....

Çözüm:

let regexp = /\.{3,}/g;
alert( "Merhaba!... Nasıl gidiyor?.....".match(regexp) ); // ..., .....

Lütfen noktanın özel bir karakter olduğunu unutmayın, bu yüzden \. ekleyerek ondan kurtulmamız gerekiyor.

#ABCDEF şeklinde yazılmış HTML-renklerini aramak için bir düzenli ifade oluşturun: önce # ve ardından 6 tane onaltılık karakter gelmesi lazım.

Bir kullanım örneği:

let regexp = /...senin duzenli ifaden.../

let str = "color:#121212; background-color:#AA00ef bad-colors:f#fddee #fd2 #12345678";

alert( str.match(regexp) )  // #121212,#AA00ef

NOT: Bu görevde #123 veya rgb(1,2,3) vb. diğer renk formatlarına ihtiyacımız yoktur.

# ve ardından 6 tane onaltılık karakterin gelmesine ihtiyacımız var.

Onaltılık bir karakter [0-9a-fA-F] şeklinde ifade edilebilir. Veya eğer i bayrağını kullanırsak, [0-9a-f] şeklinde ifade edilebilir.

Daha sonrasında {6} nicelik belirtecini kullanarak bunlardan 6 tanesini seçebiliriz.

Sonuç olarak, /#[a-f0-9]{6}/gi düzenli ifadesine sahibiz.

let regexp = /#[a-f0-9]{6}/gi;

let str = "color:#121212; background-color:#AA00ef bad-colors:f#fddee #fd2"

alert( str.match(regexp) );  // #121212,#AA00ef

Buradaki sorun daha uzun değerleri de bulmasıdır:

alert( "#12345678".match( /#[a-f0-9]{6}/gi ) ) // #12345678

Bunu çözmek için, sona \b ekleyebiliriz:

// renk
alert( "#123456".match( /#[a-f0-9]{6}\b/gi ) ); // #123456

// bir renk değil
alert( "#12345678".match( /#[a-f0-9]{6}\b/gi ) ); // null
Eğitim haritası

Yorumlar

yorum yapmadan önce lütfen okuyun...
  • Eğer geliştirme ile alakalı bir öneriniz var ise yorum yerine github konusu gönderiniz.
  • Eğer makalede bir yeri anlamadıysanız lütfen belirtiniz.
  • Koda birkaç satır eklemek için <code> kullanınız, birkaç satır eklemek için ise <pre> kullanın. Eğer 10 satırdan fazla kod ekleyecekseniz plnkr kullanabilirsiniz)