Metin uzunluğu

Metni beş biçimde birden sayın: gözle saydığınız karakterler, kod noktaları (Python’da len()), UTF-16 birimleri (JavaScript’te .length), kelimeler ve satırlar.

Girdi
Karakterler
0
Kod noktaları
0
UTF-16 birimleri
0
Kelimeler
0
Satırlar
0

«Bu dize ne kadar uzun?» sorusunun neden birden çok yanıtı var

Önemsiz bir soru gibi görünür, ama bir metin parçasının uzunluğu tümüyle neyi saydığınıza bağlıdır. Bir insan görebildiği karakterleri sayar. Bir veritabanı, bir değerin kapladığı depolamayı sayar. JavaScript ise yine başka bir şey sayar. Bu sayılar uyuşmadığında — ve emoji, aksanlı harfler ve Latin olmayan betikler için sık sık uyuşmaz — tek bir «uzunluk» yanıltıcıdır. Bu araç, durumunuz için önemli olanı seçebilesiniz diye beş anlamlı ölçüyü yan yana gösterir.

Beş ölçünün açıklaması

  • Karakterler (grafemler): bir insanın tek karakter olarak algıladığı şey. 👨‍👩‍👧 gibi bir emoji ailesi ya da birleştirici aksanlı bir harf tek sayılır — bu, «gözle» sayımıyla eşleşen değerdir.
  • Kod noktaları: Unicode skaler değerlerinin sayısı. Görünen tek bir karakter, birbirine bağlanmış birkaç kod noktasından oluşabilir; bu yüzden bu sayı çoğu zaman grafem sayısından yüksektir.
  • UTF-16 birimleri: JavaScript’in bir dizenin .length özelliğinden bildirdiği değer. Temel Çok Dilli Düzlem dışındaki karakterler (çoğu emoji) her biri iki UTF-16 birimi kaplar.
  • Kelimeler: kelime benzeri belirteçlerin sayısı; boşluklara göre saf bir bölme yerine Unicode duyarlı biçimde algılanır.
  • Satırlar: her satır sonunu sayarak, satır sayısı.

Emoji ve aksanlar saf sayımı neden bozar

Modern metin Unicode’dan oluşur; Unicode ise birçok görünen karakteri tek birimler yerine diziler olarak temsil eder. Bir bayrak emojisi iki bölgesel gösterge simgesidir. Bir aile emojisi, görünmez «sıfır genişlikli birleştirici» karakterlerle bağlanmış birkaç kişidir. Aksanlı bir é, tek bir kod noktası ya da düz bir e’nin ardından gelen birleştirici bir aksan olabilir. Bunların her biri tek karakter gibi görünür, ama ölçüye bağlı olarak iki, üç ya da daha fazla sayılabilir. Elle saymanın ya da tek bir sayıya güvenmenin hatalara yol açmasının nedeni tam da budur.

Hangi sayımı kullanmalısınız?

  • İnsanların gördüğü karakter sınırları (bir biyografi, tweet tarzı bir alan, bir SMS önizlemesi): Karakterler (grafemler) kullanın, çünkü bu, kullanıcının saydığıyla eşleşir.
  • JavaScript dize işleme, dizi indeksleme ya da dilimleme: UTF-16 birimleri kullanın, çünkü .length ve dize indeksleri buna dayanır.
  • Veritabanı sütun boyutları: sütununuzun karakterle mi yoksa baytla mı ölçüldüğünü kontrol edin — birçoğu baytla sınırlıdır ve UTF-8 baytları da tüm bu sayımlardan farklıdır.
  • Düzenleyiciler ve okunabilirlik için kelime ya da satır sayıları: Kelimeler ve Satırlar ölçülerini kullanın.

Python ve JavaScript uzunluk derken neyi kasteder

Yukarıdaki beş sayıdan ikisi, insanların buraya asıl onlar için geldiği sayılardır ve farklı dillere aittir. Python’daki len() ile JavaScript’teki .length’in ikisi de bir dizenin uzunluğu diye anlatılır, ama düz ASCII’nin ötesindeki her şeyde aynı metin için aynı anda farklı yanıt verirler. İkisi de yanlış değildir: farklı birimleri sayarlar, ve iki kutu da yukarıda yan yana durur ki fark tahmin edilmek yerine okunabilsin.

  • Python: len(), Unicode kod noktalarının sayısını verir, çünkü Python 3’te bir dize kod noktalarından oluşan bir dizidir. "Kod noktaları" kutusuna bakın — len() size o sayıyı verecektir.
  • JavaScript: .length, UTF-16 kod birimlerinin sayısını verir, çünkü bir JavaScript dizesi UTF-16 olarak tutulur. "UTF-16 birimleri" kutusuna bakın. Array.from(text).length ise dizeyi kod noktası kod noktası dolaşır ve böylece Python ile aynı sayıyı verir.
  • İkisi de gördüğünüzü saymaz. "Karakterler" kutusu grafem sayısıdır ve iki dilde de yerleşik hiçbir uzunluk onu üretmez: JavaScript için Intl.Segmenter, Python için üçüncü taraf bir paket gerekir. Uyguladığınız sınırı bir insan okuyacaksa, isteyeceğiniz kutu odur.
  • Kelimeler ile Satırlar da hiçbirinin işi değildir. İkisi de bunları boşluklara ve satır sonlarına göre bölerek yaklaşık hesaplayabilir, ama ikisi de burada gösterilen ve Unicode duyarlı olan sayılardan sapar — boşluksuz yazılan metinde, noktalama işaretlerinde ve metni bitiren bir satır sonunda.

Örnek yükle düğmesinin ardındaki örnek, farkı görmenin en hızlı yoludur. Oradaki aile emojisi okuyan için tek karakter, Python için beş kod noktası, JavaScript için sekiz UTF-16 birimidir: bu beş kod noktasının üçü Temel Çok Dilli Düzlem’in dışında kalır ve her biri iki birim tutar, aralarındaki iki görünmez birleştirici de birer birim. Yani birinin yirmi karakter yazabildiği bir alan gözle gerçekten yirmi karakter alır, oysa iki dilden birinde yazılmış saf bir denetim, sığan metni geri çevirir.

Uzunluk, bayt cinsinden boyut değildir

Yukarıdaki beş sayının hiçbiri bir bayt sayısı değildir ve ikisini birbirine karıştırmak kolaydır. Sayım, metnin kendisine ait bir özelliktir; bayt cinsinden boyut ise metin bir kodlamayla yazıldıktan sonraki özelliğidir, yani aynı dize UTF-8 ile bir boyut, UTF-16 ile başka bir boyut tutar. Baytla ölçülen şey bu yüzden kodlamadan sonra ölçülür ve hangi kodlamanın seçildiği cevabın bir parçasıdır.

  • UTF-8 neredeyse her şeyin kullandığı kodlamadır ve değişken genişliktedir: bir ASCII harfi, rakamı ya da noktalama işareti bir bayt, aksanlı ve Latin dışı karakterlerin çoğu iki ya da üç, birçok emoji ise dört bayt tutar. Yüz karakter ancak hepsi ASCII ise yüz bayttır — aynı yüz karakter Yunanca, İbranice, Arapça ya da Çince olduğunda bunun iki ila üç katıdır.
  • Python: len() kod noktalarını sayar, o yüzden ölçmeden önce kodlayın. len(text.encode('utf-8')) UTF-8 bayt sayısıdır ve oraya başka bir kodlama adı yazmak başka bir sayı verir; mesele zaten budur.
  • JavaScript: .length UTF-16 birimlerini sayar, dolayısıyla o da bir bayt sayısı değildir. new TextEncoder().encode(text).length hem tarayıcıda hem Node içinde UTF-8 bayt sayısını verir ve TextEncoder yalnızca UTF-8 üretir, yani adı yazılacak bir kodlama yoktur.
  • Bir şey saymadan önce sınırınızın hangi birimle yazıldığını denetleyin. Kimi veritabanı motorları bir sütunu karakterle, kimileri baytla tanımlar; bir HTTP başlığının değeri ve bir dosyanın boyutu bayttır; insanlar için yazılmış bir kural ise "Karakterler" kutusunun gösterdiği şeydir. Karakterle ölçülen her şey zaten yukarıdadır; baytla ölçülen her şey kodlanmış bir uzunluk ister.

Bayt sayısını elde ettikten sonra devamı Bayt boyutu dönüştürücü aracındadır: ham bayt sayısını her iki birim sistemine aynı anda çevirir — binin kuvvetlerine dayananına ve ikinin kuvvetlerine dayananına — ve makinenizdeki araçların aynı boyutu nasıl bildirdiğini gösterir. Bu sayfa kodlamanın başladığı yerde biter; öteki bir bayt sayısından başlar.

Sıkça sorulan sorular

Hangi sayım JavaScript’in dize uzunluğuyla eşleşir?
UTF-16 birimleri değeri, JavaScript’teki ham .length özelliğiyle eşleşir. Kodunuz dizeleri dilimliyor ya da indeksliyorsa, davranışını yöneten sayı budur.
Neden bir emoji birkaç karakter olarak sayılıyor?
Birçok emoji, birbirine bağlanmış birkaç Unicode kod noktasından oluşur. Grafem olarak (gördüğünüz şey) tek bir karakterdir, ama kod noktası ve UTF-16 sayıları daha yüksektir; her ölçünün ayrı gösterilmesinin nedeni budur.
Sondaki boşlukları ve satır sonlarını sayar mı?
Evet. Yapıştırdığınız her karakter, baştaki ve sondaki boşluklar ile satır sonları dahil sayılır. Toplamlarınız beklenenden yüksek görünüyorsa, görünmez sondaki boşlukları kontrol edin.
Metnim bir sunucuya gönderiliyor mu?
Hayır. Tüm sayım tarayıcınızda gerçekleşir. Yazdığınız ya da yapıştırdığınız metin cihazınızdan asla çıkmaz.
Grafem nedir?
Bir grafem, ya da «grafem kümesi», kullanıcının algıladığı bir karakterdir — birkaç temel kod noktasından oluşsa bile, bir okurun tek karakter diyeceği en küçük birim.
Baytlar bu sayımlardan nasıl farklıdır?
Baytlar kodlamaya bağlıdır. UTF-8’de bir ASCII harfi bir bayt, çoğu aksanlı ve Latin olmayan karakter iki ya da üç, birçok emoji ise dört bayttır. Buradaki beş ölçünün hiçbiri bir bayt sayımı değildir; bu yüzden baytla sınırlı alanlar için önce UTF-8’e kodlamalısınız.

İlgili araçlar

  • Bayt boyutu dönüştürücü

    Buradaki sayıların hiçbiri bayt cinsinden bir boyut değildir: boyut ancak metin kodlandıktan sonra ortaya çıkar. O sayı elinizdeyken, o sayfa onu onluk ve ikilik birimlerde yan yana okur ve her işletim sisteminin ona ne diyeceğini söyler.

  • Regex test aracı

    Düzenli ifadeleri test edin — eşleştir, değiştir, böl.

  • Metin farkı

    İki metni karşılaştırın — değişen her satır ve kelime.

  • Unicode karakter inceleyici

    Bir dizenin tam olarak hangi karakterlerden oluştuğunu görün.