Russian Qt Forum

Qt => Интернационализация, локализация => Тема начата: 24pm от Апрель 07, 2009, 17:08



Название: Транслитерация [РЕШЕНО]
Отправлено: 24pm от Апрель 07, 2009, 17:08
Пишу функцию для создания корректных веб имён, в которой использую транслитерацию русских букв:

Код:
QString CreateValidWebFileName(QString str)
{
QString fn;
int i;
QString validChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890-_,.()[]{}<>~!@#$%^&*+=?";
QString rusUpper = "АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЫЭЮЯ";
QString rusLower = "абвгдеёжзийклмнопрстуфхцчшщыэюя";
QStringList lat;
lat <<"a"<<"b"<<"v"<<"g"<<"d"<<"e"<<"jo"<<"zh"<<"z"<<"i"<<"j"<<"k"<<"l"<<"m"<<"n"
<<"o"<<"p"<<"r"<<"s"<<"t"<<"u"<<"f"<<"h"<<"c"<<"ch"<<"sh"<<"sh"<<"ie"<<"ju"<<"ja";
qDebug() << "rus=" << rusUpper;
for (i=0; i < str.size(); ++i){
qDebug() << "char="<< str[i]<<", fn="<<fn;
if ( validChars.contains(str[i]) ){
fn = fn + str[i];
}else if (str[i] == ' '){  //replace spaces
fn = fn + "_";
}else if ( rusUpper.contains(str[i]) || rusLower.contains(str[i]) ) {//transliterate
fn = fn + lat[i];
}
}
if (fn.isEmpty() ) fn = "file";
return fn;
}
но транслитерация не работает. Qt хранит все строки в UTF-8 так, что не понятно чего ему не хватает?
qDebug() в Creator выдаёт мусор:
Код:
rus= "???????????????????˜??????????????? ???????¤???¦?§???©?«?­?®??" 
char= 'ï' , fn= ""
char= 'ó' , fn= ""
char= 'í' , fn= ""
char= 'ê' , fn= ""
char= 'ò' , fn= ""
Может уже кто реализовывал это?


Название: Re: Транслитерация
Отправлено: spirit от Апрель 07, 2009, 17:14
делал такую байдень только для украинского языка.
Код
C++ (Qt)
QString Utils::createLatinName(const QString &name)
{
QString res;
static QMap<QString, QString> toTranslit;
toTranslit["а"] = 'a';
toTranslit["б"] = 'b';
toTranslit["в"] = 'v';
toTranslit["г"] = 'g';
toTranslit["д"] = 'd';
toTranslit["е"] = 'e';
toTranslit["ё"] = "jo";
toTranslit["ж"] = "zh";
toTranslit["з"] = 'z';
toTranslit["и"] = 'i';
toTranslit["й"] = 'j';
toTranslit["к"] = 'k';
toTranslit["л"] = 'l';
toTranslit["м"] = 'm';
toTranslit["н"] = 'n';
toTranslit["о"] = 'o';
toTranslit["п"] = 'p';
toTranslit["р"] = 'r';
toTranslit["с"] = 's';
toTranslit["т"] = 't';
toTranslit["у"] = 'u';
toTranslit["ф"] = 'f';
toTranslit["х"] = 'h';
toTranslit["ц"] = 'c';
toTranslit["ч"] = "ch";
toTranslit["ш"] = "sh";
toTranslit["щ"] = 'w';
toTranslit["ъ"] = '#';
toTranslit["ы"] = 'y';
toTranslit["ь"] = '\'';
toTranslit["э"] = "e";
toTranslit["ю"] = "ju";
toTranslit["я"] = "ja";
toTranslit["є"] = "je";
toTranslit["і"] = 'i';
toTranslit["ї"] = "i'";
 
for (int i = 0; i < name.length(); ++i) {
const QString ch = name.at(i);
const QString lowerCh = ch.toLower();
if (toTranslit.contains(lowerCh)) {
QString tmp = ch == lowerCh ? toTranslit[lowerCh] : toTranslit[lowerCh].toUpper();
res += tmp;
} else
res += ch;
}
 
return res;
}
 


Название: Re: Транслитерация
Отправлено: Пантер от Апрель 07, 2009, 17:15
Нужно использовать QTextCodec или tr. В поиск по форуму, тема уже затерта до дыр.


Название: Re: Транслитерация
Отправлено: lit-uriy от Апрель 07, 2009, 20:40
>>Qt хранит все строки в UTF-8 ...
Qt хранит строки в нутри себя в UTF-16


Название: Re: Транслитерация
Отправлено: 24pm от Апрель 09, 2009, 00:06
Функция готова. Так как она не является потомком QObject, то вместо tr() использую translate():
Код:
QString CreateValidWebFileName(QString str)
{
QString fn;
int i, rU, rL;
QString validChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890-_,.()[]{}<>~!@#$%^&*+=?";
QString rusUpper = QApplication::translate("pCommon","АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЫЭЮЯ", 0, QApplication::UnicodeUTF8);
QString rusLower = QApplication::translate("pCommon","абвгдеёжзийклмнопрстуфхцчшщыэюя", 0, QApplication::UnicodeUTF8);
QStringList latUpper, latLower;
latUpper <<"A"<<"B"<<"V"<<"G"<<"D"<<"E"<<"Jo"<<"Zh"<<"Z"<<"I"<<"J"<<"K"<<"L"<<"M"<<"N"
<<"O"<<"P"<<"R"<<"S"<<"T"<<"U"<<"F"<<"H"<<"C"<<"Ch"<<"Sh"<<"Sh"<<"I"<<"E"<<"Ju"<<"Ja";
latLower <<"a"<<"b"<<"v"<<"g"<<"d"<<"e"<<"jo"<<"zh"<<"z"<<"i"<<"j"<<"k"<<"l"<<"m"<<"n"
<<"o"<<"p"<<"r"<<"s"<<"t"<<"u"<<"f"<<"h"<<"c"<<"ch"<<"sh"<<"sh"<<"i"<<"e"<<"ju"<<"ja";
for (i=0; i < str.size(); ++i){
if ( validChars.contains(str[i]) ){
fn = fn + str[i];
}else if (str[i] == ' '){  //replace spaces
fn = fn + "_";
}else{
rU = rusUpper.indexOf(str[i]);
rL = rusLower.indexOf(str[i]);
if (rU > 0)         fn = fn + latUpper[rU];
else if (rL > 0)   fn = fn + latLower[rL];
}
}
if (fn.isEmpty() ) fn = "file";
return fn;
}
Спасибо всем кто откликнулся!


Название: Re: Транслитерация
Отправлено: pastor от Апрель 09, 2009, 13:37
Так как она не является потомком QObject, то вместо tr() использую translate():

Можно было использовать и tr(), она статическая:

QObject::tr("something");


Название: Re: Транслитерация [РЕШЕНО]
Отправлено: 24pm от Апрель 10, 2009, 02:24
Действительно! Заменил две длинные строки на 3 короткие - смотрится изящней:
Код:
QTextCodec::setCodecForTr(QTextCodec::codecForName("UTF-8"));
QString rusUpper = QObject::tr("АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЫЭЮЯ");
QString rusLower = QObject::tr("абвгдеёжзийклмнопрстуфхцчшщыэюя");

Спасибо! :)


Название: Re: Транслитерация [РЕШЕНО]
Отправлено: Alex03 от Апрель 10, 2009, 10:34
В данном случае ни tr() ни translate() не нужны.
Достаточно
Код:
QString rusUpper = QString::fromUtf8("АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЫЭЮЯ");
QString rusLower = QString::fromUtf8("абвгдеёжзийклмнопрстуфхцчшщыэюя");

Конечно при условии что у Вас исходник в UTF-8.