Lai gan dzīvojam 21. gadsimtā un unikods liekas pašsaprotams, reizēm nākas sastapties ar faktu, ka latviešu valodā rakstītam tekstam nākas noņemt diakritiskās zīmes. Tautas valodā runājot: "noņemt jumtiņus, garumzīmes un ķeksīšus". Viens variants ir lietot, piemēram, String.Replace() f-ju. Rezultātā nonākam pie šāda koda:
static string RemoveDiacritics_OldFashioned(string value)
{
char[] oldChars = {
'Ā', 'ā', 'Č', 'č', 'Ē', 'ē', 'Ģ', 'ģ', 'Ī', 'ī', 'Ķ', 'ķ', 'Ļ', 'ļ',
'Ņ', 'ņ', 'Ō', 'ō', 'Š', 'š', 'Ū', 'ū', 'Ž', 'ž'
};
char[] newChars = {
'A', 'a', 'C', 'c', 'E', 'e', 'G', 'g', 'I', 'i', 'K', 'k', 'L', 'l',
'N', 'n', 'O', 'o', 'S', 's', 'U', 'u', 'Z', 'z'
};
for (int i = 0; i < oldChars.Length; i++)
value = value.Replace(oldChars[i], newChars[i]);
return value;
}
Tomēr .NET platforma, kopā ar unikoda normalizāciju piedāvā variantu, kā šādu pašu efektu panākt, bez šādu aizvietošanas tabulu izmantošanas. To var izdarīt, sākotnēji veicot rakstzīmju dekompozīciju, t.i. simbolu sadalīšanu atsevišķās daļās - burtos un diakritiskajās zīmēs. Pēc tam no rezultāta atlasa tikai rakstzīmju simbolus un veic atpakaļ kompozīciju. Otrā daļa gan vairāk ir vajadzīga valodās, kur izmanto hieroglifus, latviešu valodas (un, visticamākais, visu eiropas valodu)gadījumā tas neko nemaina. Tātad, kods simbolu aizvietošanai, bet šoreiz izmantojot unikoda metodes:
static string RemoveDiacritics_Unicode(string value)
{
string decomposedString = value.Normalize(NormalizationForm.FormD);
StringBuilder sb = new StringBuilder();
for (int i = 0; i < decomposedString.Length; i++)
{
UnicodeCategory uc = CharUnicodeInfo.GetUnicodeCategory(decomposedString[i]);
if (uc != UnicodeCategory.NonSpacingMark)
sb.Append(decomposedString[i]);
}
return (sb.ToString().Normalize(NormalizationForm.FormC));
}
Lai demonstrētu metodes darbībā, noderēs šāda, vienkārša, programma:
private static void Main()
{
String diacritics = "ĀāČčĒēĢģĪīĶķĻļŅņŌōŠšŪūŽž";
Console.WriteLine("Sākumvērtība: {0}\nModerni: {1}\nVecmodīgi: {2}",
diacritics,
RemoveDiacritics(diacritics),
RemoveDiacritics_OldFashioned(diacritics));
}
Izpildot, iegūstam vienu un to pašu rezultātu:
Sākumvērtība: ĀāČčĒēĢģĪīĶķĻļŅņŌōŠšŪūŽž
Moderni: AaCcEeGgIiKkLlNnOoSsUuZz
Vecmodīgi: AaCcEeGgIiKkLlNnOoSsUuZz
Press any key to continue . . .
Loģisks jautājums - ko mums dod unikoda metožu izmantošana? Pirmkārt, mazākas ir iespējas kļūdīties. Nav vairs riska sajaukt kārtību aizvietošanas tabulu masīvos, vai aizmirstot kādu simbolu. Otrkārt, metode, bez izmaiņām, strādā arī ar citiem alfabētiem.
Nobeigumā vēl divas lietas. Pirmkārt, pirmavots no kurienes ir ņemta informācija. Otrkārt, ierakstam ir pievienots parauga programmas pirmkods.
p.s. Paldies Andrejam, kura problēma man deva iedvesmu uzrakstīt šo piemēru.