Yakında kullanıma sunulacak normal ifade özellikleri

Jakob Gruber
Yang Guo

ES2015, JavaScript dili için Unicode (/u) ve yapışkan (/y) işaretleriyle normal ifade söz diziminde yapılan önemli iyileştirmeler dahil olmak üzere birçok yeni özelliği kullanıma sundu. Ancak o günden bu yana geliştirme süreci durmadı. TC39'daki (ECMAScript standartlar gövdesi) diğer üyelerle sıkı bir ortak çalışma yürüten V8 ekibi, normal ifadeleri daha da güçlü hale getirmek için çeşitli yeni özellikler önerdi ve bunlarla birlikte tasarladı.

Bu özelliklerin şu anda JavaScript spesifikasyonuna eklenmesi için önerilmektedir. Teklifler tam olarak kabul edilmemiş olsa da TC39 sürecinin 3. aşamasında bulunmaktadır. Spesifikasyon kesinleşmeden önce ilgili teklif yazarlarına tasarım ve uygulama konusunda zamanında geri bildirim sağlayabilmek için bu özellikleri bir işaretle geri aldık (aşağıya bakın).

Bu blog yayını, bu heyecan verici geleceğin önizlemesini sunuyor. Gösterilecek örnekleri takip etmek istiyorsanız chrome://flags/#enable-javascript-harmony adresinde deneysel JavaScript özelliklerini etkinleştirin.

Adlandırılmış yakalamalar

Normal ifadeler, eşleşen metnin bir kısmını yakalayabilen yakalamalar (veya gruplar) içerebilir. Şu ana kadar geliştiriciler bu yakalamalara yalnızca dizinlerine göre başvurabilirler. Dizine bakarak yakalamanın kalıp içindeki konumu temel alınır.

const pattern = /(\d{4})-(\d{2})-(\d{2})/u;
const result = pattern.exec('2017-07-10');
// result[0] === '2017-07-10'
// result[1] === '2017'
// result[2] === '07'
// result[3] === '10'

Ancak normal ifadelerin okunması, yazılması ve kullanılması zaten zordur. Sayısal referanslar daha fazla karmaşık hale getirebilir. Örneğin, daha uzun kalıplarda belirli bir yakalamanın dizinini belirlemek zor olabilir:

/(?:(.)(.(?<=[^(])(.)))/  // Index of the last capture?

Daha da kötüsü, bir kalıpta yapılan değişiklikler potansiyel olarak mevcut tüm yakalamaların dizinlerini değiştirebilir:

/(a)(b)(c)\3\2\1/     // A few simple numbered backreferences.
/(.)(a)(b)(c)\4\3\2/  // All need to be updated.

Adlandırılmış yakalamalar, geliştiricilerin yakalamalara ad atamasına olanak tanıyarak bu sorunları azaltmaya yardımcı olan ve yakında kullanıma sunulacak bir özelliktir. Söz dizimi; Perl, Java, .Net ve Ruby'ye benzer:

const pattern = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/u;
const result = pattern.exec('2017-07-10');
// result.groups.year === '2017'
// result.groups.month === '07'
// result.groups.day === '10'

Adlandırılmış yakalamalara, adlandırılmış geri başvurularla ve String.prototype.replace aracılığıyla da referans verilebilir:

// Named backreferences.
/(?<LowerCaseX>x)y\k<LowerCaseX>/.test('xyx');  // true

// String replacement.
const pattern = /(?<fst>a)(?<snd>b)/;
'ab'.replace(pattern, '$<snd>$<fst>');                              // 'ba'
'ab'.replace(pattern, (m, p1, p2, o, s, {fst, snd}) => fst + snd);  // 'ba'

Bu yeni özellikle ilgili tüm ayrıntıları spesifikasyon teklifinde bulabilirsiniz.

noktaAll flag'i

Varsayılan olarak, normal ifadelerdeki . atomu, satır sonlandırıcıları hariç tüm karakterlerle eşleşir:

/foo.bar/u.test('foo\nbar');   // false

Bir teklif, /s işaretiyle etkinleştirilen limitAll modunu tanıtıyor. noktaAll modunda, ., çizgi sonlandırıcılarını da eşleştirir.

/foo.bar/su.test('foo\nbar');  // true

Bu yeni özellikle ilgili tüm ayrıntıları spesifikasyon teklifinde bulabilirsiniz.

Unicode özellik çıkışları

ES2015'te kullanıma sunulan Unicode farkındalığıyla birlikte, sayı olarak değerlendirilebilecek çok sayıda karakter (ör. daire içinde bir rakamı) veya kelime karakterleri (ör. kar anlamına gelen Çince karakter) ortaya çıktı.

Bunların ikisi de \d veya \w ile eşleştirilemez. Bu kısaltmaların anlamının değiştirilmesi, mevcut normal ifade kalıplarını bozacaktır.

Bunun yerine, yeni özellik çıkış dizileri kullanıma sunulmaktadır. Yalnızca /u işaretiyle belirtilen Unicode'a duyarlı normal ifadeler için kullanılabildiğini unutmayın.

/\p{Number}/u.test('①');      // true
/\p{Alphabetic}/u.test('雪');  // true

Ters, \P ile eşleştirilebilir.

/\P{Number}/u.test('①');      // false
/\P{Alphabetic}/u.test('雪');  // false

Unicode konsorsiyumu, matematik sembolleri veya Japonca Hiragana karakterleri gibi daha pek çok özellik tanımlar:

/^\p{Math}+$/u.test('∛∞∉');                            // true
/^\p{Script_Extensions=Hiragana}+$/u.test('ひらがな');  // true

Desteklenen Unicode özellik sınıflarının tam listesini geçerli spesifikasyon teklifinde bulabilirsiniz. Daha fazla örnek için bu bilgilendirici makaleye göz atın.

Onayların arkasına göz atma

İleriye dönük onaylamalar, en başından beri JavaScript'in normal ifade söz diziminin bir parçasıydı. İddiaların ardında yatan muadili, nihayet tanıtılıyor. Bazılarınız bunun uzun süredir V8'in bir parçası olduğunu hatırlıyor olabilir. ES2015'te belirtilen Unicode işaretini uygulamak için arka planda görünen iddialardan da yararlanıyoruz.

Adı, anlamını zaten gayet iyi açıklıyor. Bu işlev, bir kalıbı yalnızca arkası grubundaki kalıptan önce eşleşecek şekilde kısıtlamanın bir yolunu sunar. Hem eşleşen hem de eşleşmeyen tatlara sahiptir:

/(?<=\$)\d+/.exec('$1 is worth about ¥123');  // ['1']
/(?<!\$)\d+/.exec('$1 is worth about ¥123');  // ['123']

Daha fazla bilgi için, iddiaların arkasına bakmaya özel önceki blog yayınımıza ve ilgili V8 test senaryolarıyla ilgili örneklere göz atın.

Teşekkür

Bu blog yayını, bunu yapmak için canla başla çalışan bazı kişilerden bahsetmeden tamamlanmazdı: özellikle dil şampiyonları Mathias Bynens, Dan Ehrenberg, Claude Pache, Brian Terlson, Thomas Wood, Gorkem Yakin ve Ircontribup guru'nun diğer herkesin özelliklerini uygulamaya koyan dil şampiyonları.

Bu yeni normal ifade özelliklerinin bizim kadar heyecanlı olduğunu umuyoruz.