如何在Qt中从字符串中去除重音符号/变音符号?

6
如何在Qt中从字符串中删除变音符号。例如,这个字符串:
QString test = QString::fromUtf8("éçàÖœ");
qDebug() << StringUtil::removeAccents(test);

应该输出:

ecaOoe

https://dev59.com/hWjWa4cB1Zd3GeqPnBXa - Mudassir Hasan
4个回答

11

在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 类型,因为某些带有变音符号的字符可以匹配两个单独的字符。例如,œ => oe


除非您在替换可以规范化为单个组合字符的字形之前进行组成Unicode规范化,否则“diacriticLetters_”也需要是QStringList。 - Sebastian Negraszus
我必须将第6行替换为 diacriticLetters_ = QString("ŠŒŽšœžŸ¥µÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýÿ"); - Carl Bosch

4
你的问题有些误导性。你似乎想做的不仅是删除变音符号(œ是一个没有变音符号的连字字母)。我猜你想将任意Unicode字符串转换为大致相应的ASCII字符串?
对于变音符号,你可以执行分解Unicode规范化(NFD或NFKD,取决于你的具体需求),然后删除所有“Mark”类别的字符(QChar :: Mark_NonSpacing,QChar :: Mark_SpacingCombining和QChar :: Mark_Enclosing)。
对于其他所有内容(例如œ),我不知道通用的解决方案。创建一个带有所有所需替换的查找表,然后进行搜索和替换(参见Laurent的答案)。

1

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

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

这是部分解决方案,因为它无法将“œ”转换为“oe”。

0

有一种粗糙的方法可以部分解决您的问题(只能处理重音符号,但不能处理像“oe”这样的连字符)。

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

2
根据Qt助手,这依赖于未定义的行为! - Sebastian Negraszus

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接