mb_detect_encoding() は文字コードの妥当性検証として使用できるか(その2)

前回(mb_detect_encoding() は文字コード判定として使用できるか(その1))の続きです。
mb_check_encoding() と mb_detect_encoding() を正規表現として表わして比較してみました。各文字コードごとにまとめます。調査した PHP のバージョンは、5.2.9 で、前回の Patch を適用したもので調査しました。通常の PHP の結果とは一致しません。
間違いを発見した方はコメントなどでご指摘ください。

ASCII

正規表現
mb_detect_encoding()\A[\x00\x09\x0a\x0d\x20-\x7f]*\z
mb_check_encoding() \A[\x00-\x7f]*\z
相違点
通常、ASCII の正規表現といえば、mb_check_encoding() と同じ "\A[\x00-\x7f]*\z" と考えますが、mb_detect_encoding() では違ったものになっています。もともと、mb_detect_encoding() は複数の文字コードから妥当な文字コードを検出する関数です。このため、mb_check_encoding() と同じだと、ISO-2022-JP の文字列も ASCII と検出してしまう問題があります。 通常の ASCII とは違うような気はしますが、妥当なものになっていると思います。

SJIS

正規表現
mb_detect_encoding()\A([\x00-\x7f]|[\xa1-\xdf]|[\x81-\x9f\xe0-\xef][\x40-\x7e\x80-\xfc])*\z
mb_check_encoding() \A([\x00-\x7f]|[\xa1-\xdf]|[\x81-\x9f\xe0-\xef][\x40-\x7e\x80-\xfc])*\z
相違点
違いはありません。

SJIS-win

正規表現
mb_detect_encoding()\A([\x00-\x7f]|[\xa1-\xdf]|[\x81-\x9f\xe0-\xfc][\x40-\x7e\x80-\xfc])*\z
mb_check_encoding() \A([\x00-\x7f]|[\xa1-\xdf]|[\x81-\x9f\xe0-\xfc][\x40-\x7e\x80-\xfc])*\z (※)
※ mb_check_encoding() では一部の文字が FALSE になります。
相違点
mb_check_encoding() では、上記の正規表現から TRUE と判定されるべき 398 文字が FALSE となります。どの文字列が FALSE になるのかは以下のページを参考にしてください。

これらの文字は SJIS-win として妥当な文字ですが、mb_check_encoding() では、仕様です。SJIS-win では、mb_check_encoding() が内部でユニコードへの変換を行っています。
このため、SJIS-win の有効範囲なのに FALSE を返す文字列は Microsoft のページに掲載されている文字列と一致しています。

EUC-JP

正規表現
mb_detect_encoding()\A([\x00-\x7f]|[\xa1-\xfe][\xa1-\xfe]|\x8e[\xa1-\xdf]|\x8f[\xa1-\xfe][\xa1-\xfe])*\z
mb_check_encoding()\A([\x00-\x7f]|[\xa1-\xfe][\xa1-\xfe]|\x8e[\xa1-\xdf]|\x8f[\xa1-\xfe][\xa1-\xfe])*\z (※)
※ mb_check_encoding() では一部の文字が FALSE になります。
相違点
mb_check_encoding() では、上記の正規表現から TRUE と判定されるべき 1文字(0x8fa2b7) が FALSE になります。

eucJP-win

正規表現
mb_detect_encoding()\A([\x00-\x7f]|[\xa1-\xfe][\xa1-\xfe]|\x8e[\xa1-\xdf]|\x8f[\xa1-\xfe][\xa1-\xfe])*\z
mb_check_encoding()\A([\x00-\x7f]|[\xa1-\xfe][\xa1-\xfe]|\x8e[\xa1-\xdf]|\x8f[\xa1-\xfe][\xa1-\xfe])*\z (※)
※ mb_check_encoding() では一部の文字が FALSE になります。
相違点
mb_check_encoding() では、上記の正規表現から TRUE と判定されるべき 106 文字が FALSE になります。 どの文字列が FALSE になるのかは以下のページなどを参考にしてください。

CP51932

正規表現
mb_detect_encoding()\A([\x00-\x7f]|[\xa1-\xfe][\xa1-\xfe]|\x8e[\xa1-\xdf])*\z
mb_check_encoding()\A([\x00-\x7f]|[\xa1-\xfe][\xa1-\xfe]|\x8e[\xa1-\xdf])*\z (※)
※ mb_check_encoding() では一部の文字が FALSE になります。
相違点
CP51932 は PHP 5.2.1 から使用可能です。 mb_check_encoding() では、上記の正規表現から TRUE と判定されるべき 576 文字が FALSE になります。 eucJP-win と同様に、どの文字列が FALSE になるのかは以下のページなどを参考にしてください。

UTF-8

正規表現
mb_detect_encoding()\A([\x00-\x7f]|[\xc0-\xdf][\x80-\xbf]|[\xe0-\xef][\x80-\xbf]{2}|[\xf0-\xf7][\x80-\xbf]{3}|[\xf8-\xfb][\x80-\xbf]{4}|[\xfc-\xfd][\x80-\xbf]{5})*\z
mb_check_encoding()\A([\x00-\x7f]|[\xc2-\xdf][\x80-\xbf]|\xe0[\xa0-\xbf][\x80-\xbf]|[\xe1-\xef][\x80-\xbf]{2}|\xf0[\x90-\xbf][\x80-\xbf]{2}|[\xf1-\xf7][\x80-\xbf]{3}|\xf8[\x88-\xbf][\x80-\xbf]{3}|[\xf9-\xfb][\x80-\xbf]{4}|\xfc[\x84-\xbf][\x80-\xbf]{4}|\xfd[\x80-\xbf]{5})*\z
相違点
mb_detect_encoding() は冗長な UTF-8 表現および、サロゲートペアに相当する領域でも妥当と判定します。 PHP 5.2.10 以前の mb_check_encoding() については、以下のページを参考にしてください。

mb_check_encoding() は、冗長な UTF-8 表現は FALSE と判定されますが、サロゲートペアに相当する領域は TRUE を返します。
PHP 5.3.0 では、サロゲートペアに相当する領域も FALSE となるように修正されました。