POSIX における文字とエンコーディング(ロケール)と正規表現

Published at: 2021/05/10

POSIX において、ロケールやエンコーディングまわりの定義がどうなっているのかを確認すべく、ソースにあたりながらその定義をまとめてみる。

文字(Character)

Base Definitions > Definitions の 3.87 Character より、「1 byte 以上の byte sequence」が文字として定義されていることが分かる。 文字と byte への対応関係は(文字)エンコーディングと呼ぶが、それについての制約を纏めたのが、Base Definitions > Character Set。 いくつか要点をまとめていくと、

  • 6.1 Portable Character Set
    • POSIX 準拠のシステムは、複数のエンコーディングをサポートできるが、そのすべてにおいて、この表に有る文字(大体 ASCII + 有名な制御文字 e.g. CR/LF)をサポートする必要がある。 これらの文字を Portable Character Set と呼ぶ。
    • エンコーディングは locale によって指定ないし定義される。
    • Portable Character Set のエンコーディングについては、以下の要件を満たさなければならない。
      • すべて 1 byte で表現され、かつ char に代入したときには0~127の値になる。
      • 0-9 の文字は連続した byte で表現される。
      • NUL は 0x00 で表される。
      • ., /, \n, \r はシステムがサポートするすべてのエンコーディングにおいて、同じ byte で表される必要がある。
  • 6.2 Character Encoding
    • POSIX 準拠のシステムは、1 byte すべての値(256 個)に文字を割り当てた POSIX Locale (aka C Locale) をサポートする必要がある。
    • NUL, ., /, \n, \r のそれぞれ byte 表現は、シフト系のエンコーディングの際に、別の文字を表すことに利用されてはならない。

ロケール(Locale)

POSIX では以下のロケールが定義される。

  • LC_CTYPE: 文字クラス(Base Definitions > Definitions, 3.89 Character Class に定義がある。文字において共通の性質を持つものを集めたものに名前が付けられたもの。:space: とか。)であったりエンコーディングであったりを定義する。
  • LC_COLLATE: 文字列の並びの指定
  • LC_MONETARY: お金関係の表記方法
  • LC_NUMERIC: 数値表現の方法
  • LC_TIME: 時刻
  • LC_MESSAGES: システムUIのメッセージまわり。例えば Yes/No を表す文字列の正規表現。

正規表現(Regular Expression)

Base Definitions > Regular Expressionにてその定義がなされている。

文字関係で重要なのは、

An ordinary character is a BRE that matches itself: any character in the supported character set, except for the BRE special characters listed in BRE Special Characters.

であって、つまり、もろもろの POSIX の utility (e.g. sed)やシステム関数においてまずサポートする文字集合というものがあり、その文字集合から正規表現上特殊な振舞いをする文字を除いたものは、単なる文字としてそれ自身とマッチする正規表現を表すことになる。 ERE についても同様の記述。

なので逆に、ツールがきちんとそのロケール(エンコーディング)をサポートしているのであれば、日本語を sed や awk や正規表現に突っ込んだとしても、基本的に何も問題なく動くはずであり、特に UTF-8 であれば、 POSIX のエンコーディングにまつわる制約を自明に満たすことが可能。 ゆえに、マルチバイト文字を含む POSIX 系のスクリプトを記述する際には、 utf-8 で記述しておくのが無難である。 (最悪、1文字扱いされなかったとしても、 C Locale でも動作は well defined になるはず。)

tags: posixregexlocalecharacter-encoding