ロケールを用いた文字列のコレーション
6月 30, 2011 by 鈴木 佑 | Comments
この記事は Qt Blog の "String collation with locales" を翻訳したものです。
執筆: ddenis, 2011年6月14日
Carlos が 数ヶ月前に 書いたように Qt Earth Team では Qt の国際化、ローカライズのサポートを進めてきました。既に以下のいくつかの機能を実装しています。
- Linux/Unix で LC_MESSAGES や LC_TIME 等の環境変数を考慮するように変更
- QLocale に文字種別のサポートを追加
- 通貨のサポートを追加(不十分だというフィードバックがあったため、リリース前にさらに機能を追加しようと思っています)
- アプリケーションの翻訳のために OS から対応言語を取得、週の最初の曜日、ウィークデー、文字列のクォート、複数の文字列の結合、等々
我々の TODO リストにあるもう1つは、コレーション(collation)のサポート(QTBUG-17104)です。(これはとても複雑な話なので)馴染みが無い方のために説明すると、コレーションとは文字列を並べる順番のことです。例えば “coté” と “côte” という2つの文字列があった場合に、フランスのフランス語のロケール(fr-FR)では前者が前になるのに対して、カナダのフランス語のロケール(fr-CA)では、後者が前になります。現在の Qt でもローカライズに対応した文字列比較([qt "QString::localeAwareCompare" l=qstring m=#localeAwareCompare])ができますが、これには2つの問題があります。1つはシステムロケールしか使えないこと(どのロケールのルールかを指定できない)、もう1つは「デフォルト」の比較ルールを使用することで、これは(例えば "file10" と "file2" のような)数字の比較などを設定する方法が無いことを意味します。というわけで、私は QtCollator クラスのドラフトを実装をしてみました。このクラスは ICU ライブラリのラッパで、コレーションの機能を Qt のスタイルの API で提供します。
class QtCollator
{
public:
enum Strength {
PrimaryStrength = 1,
BaseLetterStrength = PrimaryStrength,SecondaryStrength = 2,
AccentsStrength = SecondaryStrength,TertiaryStrength = 3,
CaseStrength = TertiaryStrength,QuaternaryStrength = 4,
PunctuationStrength = QuaternaryStrength,IdenticalStrength = 5,
CodepointStrength = IdenticalStrength
};enum Option {
PreferUpperCase = 0x01,
PreferLowerCase = 0x02,
FrenchCollation = 0x04,
DisableNormalization = 0x08,
IgnorePunctuation = 0x10,
ExtraCaseLevel = 0x20,
HiraganaQuaternaryMode = 0x40,
NumericMode = 0x80
};
Q_DECLARE_FLAGS(Options, Option)QtCollator(const QLocale &locale = QLocale());
QtCollator(const QtCollator &);
~QtCollator();
QtCollator &operator=(const QtCollator &);void setLocale(const QLocale &locale);
QLocale locale() const;void setStrength(Strength);
Strength strength() const;void setOptions(Options);
Options options() const;enum CasePreference {
IgnoreCase = 0x0,
UpperCase = 0x1,
LowerCase = 0x2
};bool isCaseSensitive() const;
CasePreference casePreference() const;
void setCasePreference(CasePreference c);void setNumericMode(bool on);
bool numericMode() const;int compare(const QString &s1, const QString &s2) const;
int compare(const QStringRef &s1, const QStringRef &s2) const;
bool operator()(const QString &s1, const QString &s2) const
{ return compare(s1, s2) < 0; }QByteArray sortKey(const QString &string) const;
};
簡単なベンチマークでは(ICU の実装を使用した) QtCollator では QString::localeAwareCompare (つまり strcoll())に比べて Linux では 30 倍速く、Windows では(CompareString を使用する) localeAwareCompare よりも 5 倍速いという結果でした。
現在のコードはリサーチ用のリポジトリにあり、Qt 内部のものには一切依存していません。単に libICU ライブラリをラッピングしたもので、アドオンとしてアプリケーションから使用可能です。プラットフォームにあるかどうか分からないサードーパーティーのライブラリに依存しているものを Qt に含めるのは難しいのが現実で、さらに ICU が提供する機能のいくつかが Qt が既に持っているものと重複しているという問題もあります。1つの代替案は Unicode Collation Algorithm を実装し、CLDR のデータを直接使用する(これは既に QLocale のデータで行っています)ことです。
今のところ Qt のコレーションがどうなるかについての明確な答えはありませんが、Qt Contributors' Summit でこれが議題にあがり、今後の方向性が決まることを期待しています。
ソースコード: https://qt.gitorious.org/qt-labs/qtcollator
サンプルアプリケーション: https://qt.gitorious.org/qt-labs/qtcollator/blobs/master/qsort/main.cpp#line86
Blog Topics:
Comments
Subscribe to our newsletter
Subscribe Newsletter
Try Qt 6.8 Now!
Download the latest release here: www.qt.io/download.
Qt 6.8 release focuses on technology trends like spatial computing & XR, complex data visualization in 2D & 3D, and ARM-based development for desktop.
We're Hiring
Check out all our open positions here and follow us on Instagram to see what it's like to be #QtPeople.