Türkçe İ problemi nedir?

Türk alfabesinde iki ayrı i harfi vardır: noktalı i büyüdüğünde İ, noktasız ı büyüdüğünde I olur. JavaScript gibi yerel ayardan bağımsız dönüşüm kullanan dillerde varsayılan kural Türkçeden farklıdır: i harfi I olur, büyük İ ise küçültülürken i ile bir birleşik nokta işaretine ayrılabilir. Sonuçta aynı kod, çalıştığı ortamın yerel ayarına göre farklı metin üretir.

Bu fark yalnızca görünüşte kalmaz. Anahtar sözcük karşılaştırmaları, yetki kontrolleri, dosya ve URL adları, e-posta eşleştirmeleri ve sıralama bu davranışa dayanır. “Turkey test” diye bilinen hata sınıfı da buradan çıkar: kod, tr-TR ayarlı bir makinede çalışana kadar sorunsuz görünür.

Araç ne gösterir?

Üstteki alana her satıra bir sözcük gelecek şekilde metin yapıştırın; isterseniz ikinci alana karşılaştırma metni de yazın. Araç her satır için yedi işlemi iki kuralla hesaplar: büyük harf, küçük harf, küçültülmüş uzunluk, NFC/NFD uzunluğu, eşitlik, düzenli ifade ve slug. Satırlar ayrıca Array.prototype.sort() ve Intl.Collator("tr") ile sıralanır; farklı çıkan satırlar işaretlenir.

Farklı sonuçlar sarı zeminle ve “Fark var” etiketiyle işaretlenir; renk tek başına bilgi taşımaz. Farklı karakterlerin kod noktaları yazılır. U+0307 görünmez bir işaret olduğu için “U+0307 COMBINING DOT ABOVE” etiketiyle gösterilir. Metni dönüştürmek istiyorsanız büyük/küçük harf dönüştürücüyü kullanın; bu araç yalnızca teşhis içindir.

Örnek girdiler için JavaScript sonuçları
GirditoUpperCase()toLocaleUpperCase("tr-TR")toLowerCase()toLocaleLowerCase("tr-TR")
istanbulISTANBULİSTANBUListanbulistanbul
IğdırIĞDIRIĞDIRiğdırığdır
İzmirİZMIRİZMİRi + U+0307 + zmir (6 kod birimi)izmir
fileFILEFİLEfilefile
TITLETITLETITLEtitletıtle

Dört harf, iki çift: İ/i, I/ı ve U+0130, U+0131, U+0307

Türkçede iki çift vardır: i ile İ, ı ile I. İngilizce benzeri kural bu çiftleri i ile I olarak birleştirir. Son satır, küçültmede ortaya çıkabilen birleşik noktadır.

İ/ı ile ilgili karakterler
KarakterKod noktasıUnicode adı
İU+0130LATIN CAPITAL LETTER I WITH DOT ABOVE
iU+0069LATIN SMALL LETTER I
IU+0049LATIN CAPITAL LETTER I
ıU+0131LATIN SMALL LETTER DOTLESS I
birleşik noktaU+0307COMBINING DOT ABOVE

"İ".toLowerCase() varsayılan kuralda iki kod birimli "i\u0307", tr-TR kuralında tek harf olan i verir; ekranda aynı görünse de uzunluk ve eşitlik değişir.

Kimlik ve anahtar karşılaştırmaları için kural

Protokol adları, HTTP üstbilgileri, yapılandırma anahtarları, dosya uzantıları ve kullanıcı adı gibi makineye ait kimlikler kullanıcının diline göre değişmemelidir. Bunlar için yerel ayardan bağımsız (locale-independent) ya da sıra tabanlı (ordinal) karşılaştırma seçin.

  • Java: toUpperCase(Locale.ROOT); equalsIgnoreCase yerel ayardan bağımsızdır ama Türkçeye duyarlı değildir.
  • C#/.NET: ToUpperInvariant() ya da StringComparison.OrdinalIgnoreCase.
  • JavaScript: toLowerCase() ve toUpperCase() zaten yerel ayardan bağımsızdır; yine de hangi karakterleri kabul ettiğinizi açıkça tanımlayın, örneğin kısıtlı ASCII.

Kimliği ASCII ile sınırlamak çoğu zaman en sağlam yoldur: rastgele Unicode tanımlayıcıların eşdeğer olduğunu varsaymak yerine kabul edilen karakter kümesini siz belirlersiniz.

Kullanıcı metni için kural

Türkçe okuyucuya gösterilecek başlık, ad ve etiketlerde yerel ayarı açıkça verin: JavaScript'te toLocaleUpperCase("tr-TR"), Java'da Locale.forLanguageTag("tr-TR"), .NET'te CultureInfo("tr-TR"). Böylece istanbul sözcüğü İSTANBUL olur. Yerel ayarı ortamdan devralmak yerine kodda yazmak, aynı kodun farklı makinelerde aynı sonucu vermesini sağlar.

Python'da str.upper() yerel ayardan bağımsızdır; Türkçe büyütme için küçük bir harf eşlemesi ya da ICU tabanlı bir kütüphane gerekir. Aracın altındaki “Kod örüntüleri” paneli her dil için tuzağı ve güvenli seçeneği listeler.

Sıralama ve arama

Array.prototype.sort() dizeleri UTF-16 kod birimi sırasıyla dizer; bu sıra Türkçe alfabeyle uyuşmaz. ı i İ I ç c z ş s ü u satırlarını deneyin: varsayılan sıra I c i s u z ç ü İ ı ş, Intl.Collator("tr") sırası c ç ı I i İ s ş u ü z olur.

Arama için de aynı ilke geçerlidir. /İSTANBUL/i.test("istanbul") ve /istanbul/i.test("İSTANBUL") ifadelerinin ikisi de false döner; u bayrağı eklemek bunu değiştirmez. Türkçeye duyarlı eşleştirme için karşılaştırmadan önce iki tarafı da aynı yerel ayarla küçültün ya da localeCompare ile sensitivity seçeneğini kullanın.

Slug üretiminde ı, ş, ğ gibi harflerin ASCII karşılığına çevrilmesi gerekir; basit yöntem bu harfleri siler. Ayrıntılar için slug oluşturucuya bakın.

Sınırlar

Araç tarayıcınızın ICU verisini kullanır; sonuçlar tarayıcıya ve sürüme göre değişebilir. Türkçe yerel ayar verisi eksikse yanlış sonuç göstermek yerine uyarı verir. Buradaki JavaScript sonuçları 11 Ekim 2026'da Node v20.15.1 ve ICU 74.2 ile doğrulandı; Python'un büyük/küçük harf davranışı da çalıştırılarak denendi.

Java, C# ve SQL satırları çalıştırılmadı; resmi belgelere dayanır. Java/C#/SQL davranışı ortam ve collation ayarına bağlıdır; kendi ortamınızda doğrulayın. Girdi en fazla 10.000 satır ve 256 KiB, karşılaştırma metni 200 karakter olabilir; yapıştırdığınız hiçbir kod çalıştırılmaz.

Kaynaklar (11 Ekim 2026'da kontrol edildi): Java String, .NET dize uygulamaları, Python str.casefold, PostgreSQL collation, MySQL Unicode kümeleri.

Sık sorulan sorular

toUpperCase() ile toLocaleUpperCase("tr-TR") arasındaki fark nedir?

toUpperCase() yerel ayardan bağımsızdır ve istanbul sözcüğünü ISTANBUL yapar; toLocaleUpperCase("tr-TR") İSTANBUL yapar. Kullanıcıya görünen Türkçe metinde ikincisini kullanın.

İ küçültülünce neden iki kod birimi çıkıyor?

Unicode'un varsayılan eşlemesinde İ (U+0130) küçülürken i ve U+0307 COMBINING DOT ABOVE olur; uzunluk 1'den 2'ye çıkar. tr-TR kuralı tek harf olan i verir.

Sunucu ya da JVM yerel ayarı tr-TR olursa ne olur?

Yerel ayarı örtük alan yöntemler sonucu değiştirir. Java belgesine göre argümansız toUpperCase() varsayılan yerel ayarı kullanır; tr-TR ayarlı bir JVM'de "title".toUpperCase() TİTLE verir. .NET'te kültür belirtmeyen çağrılar geçerli kültüre bağlıdır. Kendi ortamınızda doğrulayın.

Düzenli ifadelerin i bayrağı Türkçe harfleri eşler mi?

Hayır. /istanbul/i ifadesi İSTANBUL metnini u bayrağıyla da eşlemez. İki tarafı da toLocaleLowerCase("tr-TR") ile küçültün ya da localeCompare kullanın.

Metni büyük veya küçük harfe çevirmek için hangi aracı kullanmalıyım?

Bu araç yalnızca teşhis içindir. Metni Türkçe kurallarla dönüştürmek için büyük/küçük harf dönüştürücüyü, URL için slug oluşturucuyu kullanın.

Bu konuda daha ayrıntılı bir yazı var mı?

Evet: Türkçe İ sorunu: İ/i ve ı/I yazılımı nasıl bozar yazısı sorunu kod örnekleriyle uzun biçimde anlatır.

Yayın: · Güncelleme: