localeAwareCompare的不同结果

Different results of localeAwareCompare

本文关键字:结果 localeAwareCompare      更新时间:2023-10-16

我需要比较两个包含宏字符(Ā,Ō,Ū)的UTF-8编码字符串。顺序应该是 A <Ā><Ō><Ū,这意味着不应根据马克龙字符的数值(A><Ā><Ō><Ū)进行比较,而是按词典顺序进行比较。>

为了实现这一点,我尝试使用localeAwareCompare:

QString a = QString::fromUtf8("Ā");
QString b = QString::fromUtf8("O");
int result = QString::localeAwareCompare(a, b);

使用这段代码,我在运行Mac OS和Android的台式计算机上遇到了不同的行为。在台式计算机上,结果是 -1(这是正确的,因为 Ā

localeAwareCompare 的 Qt 文档包含以下备注:

The comparison is performed in a locale- and also platform-dependent manner.

我正在使用的设备上的默认区域设置是:

  • 苹果操作系统:
    • 姓名:en_US
    • 脚本:7
    • 国家: 美国
  • 人造人:
    • 名称:"
    • 脚本:0
    • 国家: 任何国家

手动将默认区域设置设置为 en_US 无济于事。我唯一的猜测是这是由于平台依赖性。

我在这里不知所措。这种行为应该是正确的吗?如果是这样,是否有其他选项来计算所需的比较?


#include <QApplication>
#include <QString>
#include <QDebug>
int main(int argc, char** argv) {
    QApplication app(argc, argv);
    QString a = QString::fromUtf8("A");
    QString a_m = QString::fromUtf8("Ā");
    QString o = QString::fromUtf8("O");
    qDebug() << (QString::localeAwareCompare(a, a_m) < 0 ? "A < Ā" : "Ā < A");
    qDebug() << (QString::localeAwareCompare(a_m, o) < 0 ? "Ā < O" : "O < Ā");
    return app.exec();
}

您可以通过分解字符串来删除宏:

QString a = QString::fromUtf8("Ā");
QString norm = a.normalized(QString::NormalizationForm_D);
QString aOut;
// Remove all marks
Q_FOREACH(QChar ch, norm){
    QChar::Category c = ch.category();
    if (c != QChar::Mark_Enclosing &&
        c != QChar::Mark_NonSpacing &&
        c != QChar::Mark_SpacingCombining){
            aOut.append(ch);
    }
}
qDebug() << aOut; // prints "A"

然后正常比较字符串。但是,这也会破坏诸如Æ之类的字素。需要更复杂的算法来避免这种情况。

供参考:http://doc.qt.io/qt-5/qstring.html#normalized