Dize Uzunluğu Hesaplayıcı

Bir dize yapıştırın; araç uzunluğunu dört farklı anlamda raporlar, JavaScript tarzı .length (UTF-16 kod birimleri), Unicode kod noktaları, grafem kümeleri (kullanıcıların tek bir karakter olarak algıladığı şey) ve UTF-8 baytları (veritabanı sütununuzun aslında depoladığı şey). Bu sayılar emoji, bayrak ya da birleştirme işareti içeren herhangi bir dizede birbiriyle uyuşmaz, ve bu uyuşmazlık, pek çok hatanın kaynağıdır.

Dize uzunluğunun dört anlamı

  1. 1

    UTF-16 kod birimleri

    JavaScript'te `str.length`'in döndürdüğü şey. Çoğu karakter için 1, U+FFFF'in ötesindeki herhangi bir kod noktası (emoji, antik yazılar) için 2.

  2. 2

    Kod noktaları

    Her Unicode skaleri için bir tane. Emojiler her biri 1'dir; ZWJ dizileri birden fazladır.

  3. 3

    Grafem kümeleri

    Bir kullanıcının "tek bir karakter" dediği şey. `🇺🇸` 2 kod noktasıdır ama 1 grafemdir. `n̈` 2 kod noktasıdır ama 1 grafemdir.

  4. 4

    UTF-8 baytları

    Veritabanınızın depoladığı şey. ASCII = her biri 1 bayt; yaygın Avrupa = 2; CJK = 3; çoğu emoji = 4.

Örnekler

Dize JS .length Kod noktaları Grafemler UTF-8 baytları
hello 5 5 5 5
café 4 4 4 5
😀 2 1 1 4
🇺🇸 4 2 1 8
👨‍👩‍👧 (aile) 8 5 1 18
n̈ (n + iki nokta) 2 2 1 3

Sayılar neden farklı

JavaScript dizeleri UTF-16’dır, bu yüzden U+FFFF’in üzerindeki bir kod noktası bir vekil çift olarak saklanır, iki UTF-16 kod birimi. "😀".length === 2. Kullanıcılar bundan nefret eder, çünkü 😀’ı tek bir karakter olarak düşünürler.

Grafemler daha da ileri gider: bir ülke bayrağı, kullanıcının tek bir bayrak olarak gördüğü iki bölgesel gösterge kod noktasıdır. JavaScript’te "🇺🇸".length === 4, ki bu absürt gibi görünür, ama işte böyle. Grafemler üzerinde yinelemek için Intl.Segmenter (modern), grapheme-splitter kütüphanesi kullanın ya da elle ele alın.

UTF-8 baytları: veritabanınızın depoladığı şey

VARCHAR(255) türündeki bir sütun için:

  • MySQL utf8 (gerçekte: utf8mb3) içinde 255 bayttır. café 5 bayt alır, yani 51 kopya sığar.
  • MySQL utf8mb4 (gerçek UTF-8, emoji dâhil) içinde hâlâ bayttır ama kodlama 4 baytlık dizileri destekler.
  • Postgres VARCHAR(255) içinde 255 karakterdir (kod noktaları), bayt değil.
  • SQL Server VARCHAR içinde harmanlamaya göre değişir; NVARCHAR 2 baytlık UCS-2 birimlerini sayar.

Veritabanı alanlarını kullanıcının gördüğü karakter sınırına göre boyutlandırırsanız, UTF-8 sütunlarında güvenlik için bayt × 4 kullanın, her grafem kod noktası başına 4 bayta kadar yer kaplayabilir, ZWJ dizileri daha fazlasını ekler.

Twitter tarzı karakter sayımı

Twitter bir tweet’i özel bir kuralla sayar: kod noktaları, ama emojiler ve CJK ideografları 2 sayılır. %100 ASCII bir tweet 280 karakter olabilir; 140 emojili bir tweet 140 “karaktere” ulaşır.

SMS sayımı: GSM 7-bit’te 160 karakter. GSM dışı herhangi bir karakter (á, é, ñ, emoji) kodlamayı UCS-2’ye çevirir ve mesaj uzunluğunuz 70 karaktere düşer.

Pratik kullanımlar

  • Veritabanı sütunu boyutlandırma, bir geçiş yazmadan önce bayt sayısını kontrol edin.
  • API kotası uygulama, çoğu API karakterleri değil, baytları sayar.
  • Form doğrulama, kullanıcıya beklentisiyle (grafemler) eşleşen doğru bir karakter sayısı gösterin.
  • Performans hata ayıklama, bu regex neden yavaş yineliyor? Çünkü girdi kod birimlerinde grafemlerden 3 kat daha uzundur.

Sık Sorulan Sorular

O emoji, birden çok kod noktasını birleştiren bir ZWJ dizisidir (örneğin bir aile emojisi 7 kod noktasıdır). Twitter onu Unicode ağırlık kuralına göre 2 karakter sayar; editörünüz 1 grafem gösterir. İkisi de teknik olarak doğru, sadece farklı şeyleri ölçüyorlar.

UTF-8 veritabanlarında güvenlik için beklenen karakter başına 4 bayta izin verin. 100 karakterlik (grafem) bir alan VARCHAR(400) bayt olmalı ya da Postgres gibi veritabanınız karakterleri sayıyorsa, karakter seti işlemesiyle VARCHAR(100) olmalı.

JavaScript’te: kompozisyon biçimine bağlıdır. NFC birleştirilmiş (U+00E1) uzunluğu 1’dir; NFD ayrıştırılmış (U+0061 + U+0301) uzunluğu 2’dir. Aynı görünür karakter, farklı bayt dizileri.

Aile ve meslek emojileri uzun ZWJ dizileridir. Tam desteği olmayan fontlar her kod noktasını ayrı bir glif olarak işler, böylece 👨‍💻 👨+💻 olur. İşletim sistemi fontunu güncellemek bunu düzeltir.

İlgili Araçlar

Araç diğer dillerde mevcuttur