5

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

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

应该输出:

ecaOoe
4

4 回答 4

10

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_必须是 a QStringList,因为某些带有变音符号的字符可以匹配两个单个字符。例如œ=>oe

于 2012-12-23T08:04:10.050 回答
4

你的问题有点误导。您似乎想要做的不仅仅是删除变音符号(– 是没有变音符号的连字字母)。我猜您想将任何 Unicode 字符串转换为大致对应的 ASCII 字符串?

对于变音符号,您可以执行分解的 Unicode 规范化(NFD 或 NFKD,取决于您的具体需要),然后删除“标记”类别的所有字符(QChar::Mark_NonSpacingQChar::Mark_SpacingCombiningQChar::Mark_Enclosing

对于其他所有内容(例如 –),我不知道通用解决方案。创建一个包含所有您想要的替换的查找表,然后搜索和替换(请参阅 Laurent 的答案)。

于 2012-12-25T14:09:52.663 回答
1

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

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

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

于 2013-02-19T17:38:06.120 回答
0

有一种粗略的方法可以部分解决您的问题(只是重音,而不是诸如“oe”之类的连字)。

QString title=QString::fromUtf8("éçàÖ");
qDebug("%s\n", title.toLocal8Bit().data());
于 2012-12-23T09:59:43.233 回答