1 Şubat 2021 Pazartesi

Unicode Normalizasyonu

Giriş
Önce bazı kavramları bilmek lazım

Diacritic
Harflere eklenen fonetik işaretlerdir. Örneğin Fransızca'da bulunur

Transliteration
Latin alfabesi ile yazılmayan bir dilin, Latin alfabesi haline getirilmesidir.

1. Canonical (Geleneksel) Yöntem - NFD
Türkçede veya başka dillerde olan bazı harflerin yerine o harfin eşi sayılabilecek bir başka karakteri koymaya deniyor. Örneğin Türkçe 'deki Ç harfinin yerine C harfinin kullanılması gibi. Normalize edilen tek karakter, iki karakter haline gelebilir. Açıklaması şöyle
However, if you are accepting passwords that contain non-ASCII characters, you probably want to do some sort of Unicode normalization on the string (probably NFC), since there are often multiple ways to express the same logical character. For example, you could express "é" as a single code point (U+00E9) or as two code points (U+0065 U+0301), and normalization will rewrite these to the same string
Konuyla ilgili  Normal Forms yazısına bakılabilir.

Java
Şöyle yapılır.
String s = ...
s = Normalizer.normalize(s, Normalizer.Form.NFD);
QT
QT ile aksan işaretlerini atmak için Removing accents from a QString sorusundaki gibi
QString s2 = s.normalized(QString::NormalizationForm_D);
kodu kullanılabilir.

2. NFKD
NFKD daha çok Diyakritik (Mevcut harflere yapılan fonetik işaretler) harflerde kullanılıyor.
Java
Gördüğüm en iyi örnek buradaNormalizer sınıfı kullanılıyor.
Normalizer.normalize("Indianapòlis", Normalizer.Form.NFKD).
  replaceAll("\\p{InCombiningDiacriticalMarks}+", "");//Indianapolis verir
Normalizer.Form.NFKD ile Diyakritik işaretleri önce genişletiyor. (Compatibility Decomposition, yani unicode karakter iki karakter olacak şekilde bölünüyor.). Daha sonra düzenli ifade ile eklentileri siliyor.
Benzer bir örnek te Remove diacritical marks from unicode chars yazısında bulunabilir.

C#
Yunan alfabesindeki mü ve micro işareti farklı bloklarda karakterler. Aynı gösterime sahip olmalarına rağmen equals() ile karşılaştırıldıkları zaman eşit değiller. Aşağıdaki örnekte eşit olmaları sağlanıyor.
char first = 'μ';
char second = 'µ';
string firstNormalized = first.ToString().Normalize(NormalizationForm.FormKD);
string secondNormalized = second.ToString().Normalize(NormalizationForm.FormKD);
Console.WriteLine(first.Equals(second));                     // False
Console.WriteLine(firstNormalized.Equals(secondNormalized)); // True
Linux
iconv komutu kullanılabilir.

Hiç yorum yok:

Yorum Gönder