Astral uçak kodu puanlarıyla ilgili mevcut cevaplarda hiç bir şey görmedim veya uluslararasılaşma . “Büyük harf”, belirli bir komut dosyası kullanarak her dilde aynı anlama gelmez.
Başlangıçta astral uçak kod noktaları ile ilgili sorunları ele alan herhangi bir cevap görmedim. Bir tane var , ama biraz gömülü (sanki böyle olacak, sanırım!)
Önerilen işlevlerin çoğu şöyle görünür:
function capitalizeFirstLetter(str) {
return str[0].toUpperCase() + str.slice(1);
}
Bununla birlikte, bazı kasalı karakterler BMP'nin dışında kalır (temel çok dilli düzlem, kod noktaları U + 0 ila U + FFFF). Örneğin şu Deseret metnini alın:
capitalizeFirstLetter("𐐶𐐲𐑌𐐼𐐲𐑉"); // "𐐶𐐲𐑌𐐼𐐲𐑉"
Dizelerin dizi dizinli özellikleri “karakterlere” veya kod noktalarına * erişmediği için buradaki ilk karakter büyük harfle yazılmaz. UTF-16 kod birimlerine erişirler. Bu, dilimleme sırasında da geçerlidir - dizin değerleri kod birimlerini gösterir.
UTF-16 kod birimleri, U + 0 ila U + D7FF ve U + E000 ila U + FFFF dahil olmak üzere iki aralıkta USV kod noktalarına sahip 1: 1'dir. Çoğu kasalı karakter bu iki aralığa girer, ancak hepsi değil.
ES2015'ten itibaren bununla başa çıkmak biraz daha kolay oldu. String.prototype[@@iterator]
kod noktalarına karşılık gelen dizeler verir **. Örneğin, bunu yapabiliriz:
function capitalizeFirstLetter([ first, ...rest ]) {
return [ first.toUpperCase(), ...rest ].join('');
}
capitalizeFirstLetter("𐐶𐐲𐑌𐐼𐐲𐑉") // "𐐎𐐲𐑌𐐼𐐲𐑉"
Daha uzun teller için, bu muhtemelen çok verimli değildir *** - gerisini gerçekten yinelememiz gerekmez. String.prototype.codePointAt
İlk (olası) mektuba ulaşmak için kullanabiliriz , ancak dilimin nereden başlaması gerektiğini hala belirlememiz gerekir. Kalanı yinelemekten kaçınmanın bir yolu, ilk kod noktasının BMP dışında olup olmadığını test etmek olacaktır; değilse, dilim 1'den başlar ve öyleyse dilim 2'den başlar.
function capitalizeFirstLetter(str) {
const firstCP = str.codePointAt(0);
const index = firstCP > 0xFFFF ? 2 : 1;
return String.fromCodePoint(firstCP).toUpperCase() + str.slice(index);
}
capitalizeFirstLetter("𐐶𐐲𐑌𐐼𐐲𐑉") // "𐐎𐐲𐑌𐐼𐐲𐑉"
Bunun yerine bitsel matematiği kullanabilirsiniz > 0xFFFF
, ancak muhtemelen bu şekilde anlamak daha kolaydır ve her ikisi de aynı şeyi başarır.
Gerekirse bu mantığı biraz daha ileri götürerek bu çalışmayı ES5 ve aşağısında da yapabiliriz. ES5'te kod noktalarıyla çalışmak için gerçek bir yöntem yoktur, bu nedenle ilk kod biriminin bir vekil olup olmadığını manuel olarak test etmeliyiz ****:
function capitalizeFirstLetter(str) {
var firstCodeUnit = str[0];
if (firstCodeUnit < '\uD800' || firstCodeUnit > '\uDFFF') {
return str[0].toUpperCase() + str.slice(1);
}
return str.slice(0, 2).toUpperCase() + str.slice(2);
}
capitalizeFirstLetter("𐐶𐐲𐑌𐐼𐐲𐑉") // "𐐎𐐲𐑌𐐼𐐲𐑉"
Başlangıçta uluslararasılaşma hususlarından da bahsettim. Bunların bazılarını açıklamak çok zordur, çünkü sadece hangi dilin kullanıldığına dair bilgiye ihtiyaç duymazlar, aynı zamanda dildeki kelimelerin spesifik bilgisini de gerektirebilirler. Örneğin, İrlandalı "mb" digrafisi bir kelimenin başında "mB" olarak büyük harf kullanır. Başka bir örnek, Alman eszett, asla bir kelime (afaik) başlatmaz, ancak yine de sorunu göstermeye yardımcı olur. Küçük eszett (“ß”) “SS” olarak büyük harfle yazılır, ancak “SS”, “ß” veya “ss” ile küçük harfle ifade edilebilir - hangisinin doğru olduğunu bilmek için Almanca dışında bant dışı bilgi sahibi olmanız gerekir!
Bu tür sorunların en ünlü örneği, muhtemelen Türkçedir. Türkçe Latince'de, i'nin büyük şekli İ, i'nin küçük harfi ise - iki farklı harftir. Neyse ki bunu hesaba katmanın bir yolu var:
function capitalizeFirstLetter([ first, ...rest ], locale) {
return [ first.toLocaleUpperCase(locale), ...rest ].join('');
}
capitalizeFirstLetter("italy", "en") // "Italy"
capitalizeFirstLetter("italya", "tr") // "İtalya"
Bir tarayıcıda, kullanıcının en çok tercih ettiği dil etiketi ile gösterilir navigator.language
, tercih sırasına göre bir liste bulunur navigator.languages
ve belirli bir DOM öğesinin dili (genellikle) Object(element.closest('[lang]')).lang || YOUR_DEFAULT_HERE
çok dilli belgelerde elde edilebilir .
Reg20p'de ES2018'de tanıtılan Unicode özellik karakter sınıflarını destekleyen aracılarda, ilgilendiğimiz karakterleri doğrudan ifade ederek işleri daha da temizleyebiliriz:
function capitalizeFirstLetter(str, locale=navigator.language) {
return str.replace(/^\p{CWU}/u, char => char.toLocaleUpperCase(locale));
}
Bu, bir dizede birden çok kelimeyi büyük harflerle oldukça iyi bir doğrulukla ele almak için biraz değiştirilebilir. CWU
Ya Changes_When_Uppercased karakter özelliği, iyi, değişim Büyük harfli tüm kod noktalarını eşleşir. Bunu Flemenkçe ij gibi başlıklı digraph karakterleriyle deneyebiliriz , örneğin:
capitalizeFirstLetter('ijsselmeer'); // "IJsselmeer"
Yazma sırasında (Şubat 2020), Firefox / Spidermonkey henüz son iki yılda tanıtılan RegExp özelliklerinden hiçbirini uygulamadı *****. Bu özelliğin mevcut durumunu Kangax uyumlu tablodan kontrol edebilirsiniz . Babel, RegExp değişmez değerlerini bunlar olmadan eşdeğer kalıplara özellik başvurularıyla derleyebilir, ancak ortaya çıkan kodun çok büyük olabileceğini unutmayın.
Büyük olasılıkla, bu soruyu soran insanlar Deseret kapitalizasyonu veya uluslararasılaşmasıyla ilgilenmeyecektir. Ancak bu sorunların farkında olmak iyidir, çünkü şu anda endişe olmasalar bile, sonunda karşılaşma şansınız yüksektir. Onlar “uç” vakalar değiller, daha doğrusu, tanım gereği uç vakalar değiller - zaten çoğu insanın Türkçe konuştuğu ve kod noktalarıyla kod birimlerini karıştırmanın oldukça yaygın bir hata kaynağı olduğu bir ülke var (özellikle emoji ile ilgili). Hem teller hem de dil oldukça karmaşık!
* UTF-16 / UCS2'nin kod birimleri de Unicode kod noktalarıdır, örneğin U + D800 teknik olarak bir kod noktasıdır, ancak burada "ne demek" değildir ... bulanık. Suretler kesinlikle değildir, USV'lerdir (Unicode skaler değerleri).
** Bir vekil kod birimi “yetim” ise - yani mantıklı bir çiftin parçası olmasa da - burada da vekil alabilirsiniz.
*** olabilir. Test etmedim. Büyük harf kullanımını anlamlı bir darboğaz olarak belirlemediyseniz, muhtemelen terlemezdim - en net ve okunabilir olduğuna inandığınız her şeyi seçin.
**** böyle bir işlev, ilk birimin yetim bir vekil olması mümkün olduğundan, sadece birincisi yerine hem birinci hem de ikinci kod birimlerini test etmek isteyebilir. Örneğin "\ uD800x" girdisi, X'i olduğu gibi büyük harflerle yazılır ve bu beklenen veya beklenmeyebilir.
***** İşte ilerlemeyi daha doğrudan takip etmek istiyorsanız Bugzilla sorunu .