ロケールを用いた文字列のコレーション
June 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.5 Now!
Download the latest release here: www.qt.io/download.
Qt 6.5 is the latest Long-Term-Support release with all you need for C++ cross-platform app development.
Explore Qt World
Check our Qt demos and case studies in the virtual Qt World
We're Hiring
Check out all our open positions here and follow us on Instagram to see what it's like to be #QtPeople.
Näytä tämä julkaisu Instagramissa.Henkilön Qt (@theqtcompany) jakama julkaisu