我需要比较两个包含宏字符(Ā,Ō,Ū)的UTF-8编码字符串。顺序应为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
国家:美国
Android:
名称: ””
剧本:0
国家:AnyCountry
手动将默认语言环境设置为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
关于android - localeAwareCompare的不同结果,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/35612232/