JavaSvet - otvorena java zajednica

 
glavna stranica arr2javasvet  english version arr2java.net

Od ћирилице do latinice i obratno

Dejan Krsmanović
21 Jun 2004

Java je programski jezik koji je u startu zamišljen kao jezik za Internet. Kao takav, velika pažnja je poklonjena radu sa ne-engleskim slovima što nama sa srpskog govornog područja olakšava mnoge stvari. Kako smo jedan od retkih naroda u svetu sa dva pisma, imamo i određene probleme koje drugi nemaju. U ovom tekstu biće opisan način konverzije teksta iz ćirilice u latinicu i obrnuto, a koja se može koristiti za prevođenje teksta iz jednog u drugo pismo u runtime. Na taj način, moguće je imati kompletno preveden sajt na ćirilicu i latinicu zajedno sa podacima iz baze, pri čemu je potrebno održavati samo jednu verziju.

Unicode

Kao prvo, svaki karakter u Javi se čuva u Unicode formatu, to će reći da je za čuvanje svakog karaktera potrebno dva bajta. Na ovaj način jedinstveno je moguće predstaviti slova u većini svetskih jezika.  Svako slovo naće ćirilice i latinice ima jedinstveni Unicode kod. Naša latinica je većim delom pokrivena ASCII karakterima te sa njima nema problema. Karakteri koji nisu deo ASCII standarda su pojedina slova iz latinice (ČĆŠĐ...) kao i kompletna ćirilica. Ovi karakteri se u kodu moraju predstaviti u formatu \uxxxx gde je xxxx heksadecimalni zapis Unicode koda. Na primer, slovo Š se predstavlja kao \u0160.

Ćirilično-latinična konverzija

Konvertovanje teksta iz ćirilice u latinicu je jednoznačno. Ovo je zbog toga to je ćirilica savršenije pismo (neki kažu i najsavršenije) jer svaki glas ima svoje slovo. To znači da bi analizom teksta, svakom ćiriličnom slovu odgovaralo jedno ili dva latinična. Na primer slovo њ mapira se u dva latinična slova - nj. Slova koja ne pripadaju srpskoj ćirilici je najbolje ignorisati i ostavljati ih takve kakvi su jer se verovatno radi o nekoj stranoj reči.

Latinino-ćirilina konverzija

Konverzija iz srpske latinice u ćirilicu je daleko teže. Kao prvo, praktično je nemoguće razlikovati strane reči koje ne treba prevoditi od reči koje treba prevoditi. Drugo, neka slova u latinici poput lj, nj ili dj predstavljaju poseban problem jer je teško razlikovati da li se radi o јеdnom ili dva slova. Na primer, iako je moguće prilikom nailaska na slovo 'n' proveriti da li je iza njega slovo 'j' ovo ne znači da ova dva slova predstavljaju slovo 'nj'. Na primer, reč injekcija bi trebalo da se kovertuje u инјекција, a ne u ињекција. Mnogi slovo u latinici pišu sa dj, to je takođe problem kao na primer u reči  'odjava'.

Implementacija

Konverziju iz jednog pisma u drugo u runtime, najlakše je obaviti tako što ćemo mapirati svako slovo iz srpske ćirilice u latinicu i obrnuto. Na taj način je moguće napraviti metod koji će analizirati neku reč i svaki karakter iz jednog pisma zameniti odgovarajućim iz drugog. Mapiranje se može vršiti korišćenjem  Map klasa. Pošto mape rade sa objektima, to znači da ćirilina slova možemo čuvati kao objekte klase Character (jer je dovoljan jedan znak), dok je za latinočna slova potrebno koristiti String pošto mogu sadražti dva karaktera. Kako je već pomenuto, ćirilina konverzija je jednostavnija:

public static String cyrilicToLatin(String cyrilicText) {
   
StringBuffer cyrBuffer = new StringBuffer(cyrilicText);
    StringBuffer latinBuffer =
new StringBuffer();
   
for (int i = 0; i < cyrBuffer.length(); i++) {
       
char c = cyrBuffer.charAt(i);
        Character character =
new Character(c);
       
if (cyrMapping.containsKey(character)) {
           
latinBuffer.append(cyrMapping.get(character));
       
} else {
           
latinBuffer.append(c);
       
}
    }
   
return latinBuffer.toString();
}

Latinična konverzija je malo složenija:

public static String latinToCyrilic(String latinText) {
   
StringBuffer latBuffer = new StringBuffer(latinText);
    StringBuffer cyrBuffer =
new StringBuffer();

   
for (int i=0; i < latBuffer.length(); i++) {
       
String s = latBuffer.substring(i, i+1);
       
if (i < latBuffer.length() - 1 ) {
           
char c = latBuffer.charAt(i+1);
           
if (((s.equals("D") || s.equals("d")
           
|| s.equals("L") || s.equals("l")
           
|| s.equals("N") || s.equals("n")) && (c == 'J' || c == 'j'))) {
               
s = s + 'j';
                i++;
       
} else if ((s.equals("D") || s.equals("d")) && (c == '\u017D' || c == '\u017E')) {
           
s = s + '\u017E';
            i++;
       
}
    }
   
if (latMapping.containsKey(s)) {
       
cyrBuffer.append(((Character)latMapping.get(s)).charValue());
   
} else {
       
cyrBuffer.append(s);
   
}
    }
return cyrBuffer.toString();
}

Latinčina konverzija ne daje 100% dobre rezultate, ali u većini slučajeva je zadovoljavajuća. Kompletnu klasu možete preuzeti ovde. Siguran sam da je moguće uraditi mnoge optimizacije, ali za potrebe koje imam ovo radi zadovoljavajuće. Ako podatke koristi samo Vaša aplikacija, moj savet je da čuvate ćiriličnu verziju, a latiničnu da dobijate konverzijom.

Za kraj...

Većina Java programera kod nas radi za strane firme i strano tržište te su im problemi sa srpskim slovima nepoznati. Oni koji nemaju tu sreću, znaju kolike probleme nosi lokalizacija na srpski jezik. Konverzija iz ćirilice u latinicu u memoriji je samo jedan od (lakših) problema. Tu su problemi sa radom sa različitim kodnim stranama, sortiranjem teksta (pogledajte članak Nikole Zifre), indeksiranje i pretraživanje srpskog teksta itd. Kod koji je predstavljen u ovom je deo projekta na kojem radim, a koji se bavi upravo ovakvim problemima. Ideja mi je da projekat postavim na SourceForge, kako bi se omogućilo i drugim programerima da ga koriste i poboljšaju. Pozivam sve zainteresovane na saradnju!