地域化

Boost.Regex は実行時の地域化について広範のサポートを提供する。この地域化モデルは、フロントエンドとバックエンドの2つの部分に分けられる。

フロントエンドの地域化は、エラーメッセージや正規表現構文そのものといったユーザが実際に触れるすべてのものに深く関わる。例えばフランス語のアプリケーションは [[:word:]][[:mot:]] に、\w\m に変更できる。フロントエンドのロカールを変更するには、地域化済み文字列を含んだメッセージカタログを開発者が提供しなければならない。フロントエンドのロカールは LC_MESSAGES カテゴリのみの影響を受ける。

バックエンドの地域化は、正規表現を解析した後に起こるすべてのこと、言い換えるとユーザが直接触れないすべてのものに深く関わる。大文字小文字の変換、照合、文字クラスのメンバーシップがそうである。バックエンドのロカールは開発者の介在を要求しない。ライブラリは現在のロカールについて必要なすべての情報を、オペレーティングシステムや実行時ライブラリから得る。これは例えば正規表現が C++ プログラムに組み込まれている場合など、プログラムのユーザが正規表現に直接触れない場合、ライブラリがすべてを取り計らうので明示的な地域化は不要ということを意味する。例えばコードに組み込まれた正規表現 [[:word:]]+ は常に単語全体にマッチし、プログラムが例えばギリシャ語ロカールのマシンで走っている場合は、ラテン文字ではなくギリシャ文字の単語全体にマッチする。バックエンドのロカールは LC_TYPE および LC_COLLATE カテゴリの影響を受ける。

個別の地域化の機構が 3 つ、Boost.Regex によりサポートされている。

Win32 地域化モデル

ライブラリを Win32 のもとでコンパイルした場合の既定で、特性クラス w32_regex_traits によりカプセル化される。このモデルを使用する場合、basic_regex オブジェクトは各自で LCID を保持する。既定ではこれは GetUserDefaultLCID が返すユーザ既定の設定だが、必要な場合は basic_regex オブジェクトの imbue を呼び出して他の LCID を設定することも可能である。Boost.Regex が使用する設定はすべて C 実行時ライブラリ経由で直接オペレーティングシステムから得る。フロントエンドの地域化では、ユーザ定義文字列の入ったストリングテーブルを含むリソース DLL が必要である。特性クラスは関数

static std::string set_message_catalogue(const std::string& s);

をエクスポートし、あらゆる正規表現をコンパイルする前(basic_regex インスタンスを構築する前である必要はない)にリソース DLL の名前を識別する文字列とともに呼び出す必要がある。

boost::w32_regex_traits<char>::set_message_catalogue("mydll.dll");

NT のもとではライブラリは Unicode を完全にサポートする。9x においては限定的であり、0 から 255 までの文字はサポートするが残りは「不明な」図形文字として扱う。

C 地域化モデル

C++ ロカールがあるので、C++ ロカールをサポートする非 Win32 コンパイラではこのモデルは非推奨である。このロカールは特性クラス c_regex_traits によりカプセル化され、Win32 ユーザはプリプロセッサシンボル BOOST_REGEX_USE_C_LOCALE を定義してこのモデルを有効化できる。このモデルが有効な場合、setlocale で設定可能な大域ロカールが 1 つだけ存在することになる。すべての設定は実行時ライブラリから得るため、したがって Unicode サポートは実行時ライブラリの実装による。

フロントエンドの地域化はサポートしない。

setlocale を呼び出すとコンパイル済みの正規表現がすべて無効になることに注意していただきたい。setlocale(LC_ALL, "C") を呼び出すと、このライブラリの動作は大部分の旧式の正規表現ライブラリ(本ライブラリのバージョン 1 含む)と同じになる。

C++ 地域化モデル

Windows 以外のコンパイラではこのモデルが既定である。

このモデルが有効な場合、basic_regex の各インスタンスは自身の std::locale を持つ。また、basic_regex クラスは正規表現のインスタンスごとにロカールを設定するメンバ関数 imbue を持つ。フロントエンドの地域化には POSIX メッセージカタログが必要であり、正規表現が使用するロカールの std::messages ファセットにより読み込まれる。特性クラスは次のシンボルをエクスポートし、

static std::string set_message_catalogue(const std::string& s);

メッセージカタログの名前を識別する文字列を使って、あらゆる正規表現をコンパイルする前に呼び出す必要がある(が、basic_regex インスタンスを構築する前である必要はない)。

boost::cpp_regex_traits<char>::set_message_catalogue("mycatalogue");

basic_regex<>::imbue を呼び出すと、その basic_regex インスタンスの正規表現が無効になることに注意していただきたい。

ライブラリを既定以外の地域化モデルでビルドした場合、サポートライブラリをビルドするときと、<boost/regex.hpp><boost/cregex.hpp> をインクルードするときの両方で、適切なプリプロセッサシンボル(BOOST_REGEX_USE_C_LOCALEBOOST_REGEX_USE_CPP_LOCALE)を定義しなければならない。この場合は <boost/regex/user.hpp>#define を追加するのが最適である。

メッセージカタログの提供

ライブラリのフロントエンドを地域化するためには、リソース DLL のストリングテーブル(Win32 モデル)か POSIX メッセージカタログ(C++ モデル)に適切なメッセージ文字列を含めたライブラリを提供する必要がある。後者の場合、カタログのメッセージセット 0 にメッセージを入れておかなければならない。メッセージとその ID は以下のとおりである。

メッセージ ID

意味

既定値

101

部分式の開始に使用する文字。

"("

102

部分式の終了宣言に使用する文字。

")"

103

行末表明の表現に使用する文字。

"$"

104

行頭表明の表現に使用する文字。

"^"

105

「あらゆる文字にマッチする正規表現」の表現に使用する文字。

"."

106

0 回以上の繰り返しにマッチする演算子。

"*"

107

1 回以上の繰り返しにマッチする演算子。

"+"

108

0 回か 1 回の繰り返しにマッチする演算子。

"?"

109

文字集合開始文字。

"["

110

文字集合終了文字。

"]"

111

選択演算子。

"|"

112

エスケープ文字。

"\"

113

ハッシュ文字。

"#"

114

範囲演算子。

"-"

115

繰り返し演算子開始文字。

"{"

116

繰り返し演算子終了文字。

"}"

117

数字。

"0123456789"

118

エスケープ文字の直後に置いて単語境界表明を表現する文字。

"b"

119

エスケープ文字の直後に置いて非単語境界表明を表現する文字。

"B"

120

エスケープ文字の直後に置いて単語先頭表明を表現する文字。

"<"

121

エスケープ文字の直後に置いて単語終端表明を表現する文字。

">"

122

エスケープ文字の直後に置いて単語構成文字を表現する文字。

"w"

123

エスケープ文字の直後に置いて非単語構成文字を表現する文字。

"W"

124

エスケープ文字の直後に置いてバッファ先端表明を表現する文字。

"`A"

125

エスケープ文字の直後に置いてバッファ終端表明を表現する文字。

"'z"

126

改行文字。

"\n"

127

カンマ演算子。

","

128

エスケープ文字の直後に置いてベル文字を表現する文字。

"a"

129

エスケープ文字の直後に置いてフォームフィード文字を表現する文字。

"f"

130

エスケープ文字の直後に置いて改行文字を表現する文字。

"n"

131

エスケープ文字の直後に置いて復改文字を表現する文字。

"r"

132

エスケープ文字の直後に置いてタブ文字を表現する文字。

"t"

133

エスケープ文字の直後に置いて垂直タブ文字を表現する文字。

"v"

134

エスケープ文字の直後に置いて 16 進定数を表現する文字。

"x"

135

エスケープ文字の直後に置いて ASCII エスケープ文字の開始を表現する文字。

"c"

136

コロン文字。

":"

137

イコール文字。

"="

138

エスケープ文字の直後に置いて ASCII エスケープ文字を表現する文字。

"e"

139

エスケープ文字の直後に置いて小文字を表現する文字。

"l"

140

エスケープ文字の直後に置いて非小文字を表現する文字。

"L"

141

エスケープ文字の直後に置いて大文字を表現する文字。

"u"

142

エスケープ文字の直後に置いて非大文字を表現する文字。

"U"

143

エスケープ文字の直後に置いて空白類文字を表現する文字。

"s"

144

エスケープ文字の直後に置いて非空白類文字を表現する文字。

"S"

145

エスケープ文字の直後に置いて 10 進数字を表現する文字。

"d"

146

エスケープ文字の直後に置いて非 10 進数字を表現する文字。

"D"

147

エスケープ文字の直後に置いて引用終了演算子を表現する文字。

"E"

148

エスケープ文字の直後に置いて引用開始演算子を表現する文字。

"Q"

149

エスケープ文字の直後に置いて Unicode 結合文字シーケンスを表現する文字。

"X"

150

エスケープ文字の直後に置いて単一文字を表現する文字。

"C"

151

エスケープ文字の直後に置いてバッファ終端演算子を表現する文字。

"Z"

152

エスケープ文字の直後に置いて継続表明を表現する文字。

"G"

153

(? の直後に置いてゼロ幅否定前方先読み表明を表現する文字。

"!"

カスタムのエラーメッセージは以下のように読み込まれる。

メッセージ ID

エラーメッセージ ID

既定の文字列

201

REG_NOMATCH

"No match"

202

REG_BADPAT

"Invalid regular expression"

203

REG_ECOLLATE

"Invalid collation character"

204

REG_ECTYPE

"Invalid character class name"

205

REG_EESCAPE

"Trailing backslash"

206

REG_ESUBREG

"Invalid back reference"

207

REG_EBRACK

"Unmatched [ or [^"

208

REG_EPAREN

"Unmatched ( or \("

209

REG_EBRACE

"Unmatched \{"

210

REG_BADBR

"Invalid content of \{\}"

211

REG_ERANGE

"Invalid range end"

212

REG_ESPACE

"Memory exhausted"

213

REG_BADRPT

"Invalid preceding regular expression"

214

REG_EEND

"Premature end of regular expression"

215

REG_ESIZE

"Regular expression too big"

216

REG_ERPAREN

"Unmatched ) or \)"

217

REG_EMPTY

"Empty expression"

218

REG_E_UNKNOWN

"Unknown"

カスタムの文字クラス名は以下のように読み込まれる。

メッセージ ID

説明

等価な既定クラス名

300

アルファベット文字と数字の文字クラス名。

"alnum"

301

アルファベット文字の文字クラス名。

"alpha"

302

制御文字の文字クラス名。

"cntrl"

303

10 進数字の文字クラス名。

"digit"

304

図形文字の文字クラス名。

"graph"

305

小文字の文字クラス名。

"lower"

306

印字可能文字の文字クラス名。

"print"

307

区切り文字の文字クラス名。

"punct"

308

空白の文字クラス名。

"space"

309

大文字の文字クラス名。

"upper"

310

16 進数字の文字クラス名。

"xdigit"

311

行区切り以外の空白類文字の文字クラス名。

"blank"

312

単語構成の文字クラス名。

"word"

313

Unicode 文字の文字クラス名。

"unicode"

最後にカスタムの照合要素名はメッセージ ID 400 から読み込まれ、最初に失敗したところで終了する。各メッセージは “tagname string” のような形式で、tagname[[.tagname.]] の内部で使用する名前、string は照合要素の実際のテキストである。照合要素 [[.zero.]] の値は文字列から数値への変換に使用され、他の値で置換するとその値が文字列解析に使われるということに注意していただきたい。例えば正規表現内でラテン数字の代わりに Unicode のアラビア-インド数字を使用するのであれば、[[.zero.]] に Unicode 文字 0x0660 を充てればよい。

カスタム名を定義した場合でも、文字クラスおよび照合要素の POSIX 定義名は常に有効であるということに注意していただきたい。一方、カスタムのエラーメッセージとカスタムの構文メッセージは既存のものを上書きする。