如何从Qt中的字符串中删除重音符号/变音符号?

时间:2012-12-23 08:01:02

标签: string qt diacritics qstring

如何从Qt中的字符串中删除变音符号。例如,这个:

QString test = QString::fromUtf8("éçàÖœ");
qDebug() << StringUtil::removeAccents(test);

应输出:

ecaOoe

4 个答案:

答案 0 :(得分:8)

Qt中没有直观的内置解决方案。在大多数情况下应该起作用的简单解决方案是循环遍历字符串并用等效字符替换每个字符:

QString StringUtil::diacriticLetters_;
QStringList StringUtil::noDiacriticLetters_;

QString StringUtil::removeAccents(QString s) {
    if (diacriticLetters_.isEmpty()) {
        diacriticLetters_ = QString::fromUtf8("ŠŒŽšœžŸ¥µÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýÿ");
        noDiacriticLetters_ << "S"<<"OE"<<"Z"<<"s"<<"oe"<<"z"<<"Y"<<"Y"<<"u"<<"A"<<"A"<<"A"<<"A"<<"A"<<"A"<<"AE"<<"C"<<"E"<<"E"<<"E"<<"E"<<"I"<<"I"<<"I"<<"I"<<"D"<<"N"<<"O"<<"O"<<"O"<<"O"<<"O"<<"O"<<"U"<<"U"<<"U"<<"U"<<"Y"<<"s"<<"a"<<"a"<<"a"<<"a"<<"a"<<"a"<<"ae"<<"c"<<"e"<<"e"<<"e"<<"e"<<"i"<<"i"<<"i"<<"i"<<"o"<<"n"<<"o"<<"o"<<"o"<<"o"<<"o"<<"o"<<"u"<<"u"<<"u"<<"u"<<"y"<<"y";
    }

    QString output = "";
    for (int i = 0; i < s.length(); i++) {
        QChar c = s[i];
        int dIndex = diacriticLetters_.indexOf(c);
        if (dIndex < 0) {
            output.append(c);
        } else {
            QString replacement = noDiacriticLetters_[dIndex];
            output.append(replacement);
        }
    }

    return output;
}

请注意,noDiacriticLetters_必须是QStringList,因为带有变音符号的某些字符可以匹配两个单个字符。例如œ =&gt; oe

答案 1 :(得分:3)

你的问题有点误导。你似乎想做的不仅仅是删除变音符号( - 是没有变音符号的连字。)我想你想把任何Unicode字符串变成一个粗略对应的ASCII字符串吗?

对于变音符号,您可以执行分解Unicode规范化(NFD或NFKD,具体取决于您的特定需求),然后删除“标记”类别的所有字符(QChar::Mark_NonSpacingQChar::Mark_SpacingCombining和{{ 1}})。

对于其他一切(例如œ),我不知道通用的解决方案。创建一个包含所有所需替换项的查找表,然后搜索并替换(请参阅Laurent的答案)。

答案 2 :(得分:1)

部分解决方案是使用QString :: normalized,而不是删除特殊字符。

QString test = QString::fromUtf8("éçàÖœ");
QString stringNormalized = test.normalized (QString::NormalizationForm_KD);
stringNormalized.remove(QRegExp("[^a-zA-Z\\s]"));

然而,这是部分解决方案,因为它不会将“œ”转换为“oe”。

答案 3 :(得分:0)

有部分解决问题的粗俗方法(只是重音符号,而不是“oe”等连字符。)

QString title=QString::fromUtf8("éçàÖ");
qDebug("%s\n", title.toLocal8Bit().data());