Shift_JISのダメ文字


Shift_JIS(SJIS, cp932) の文字コードで、2byte目が0x5c の \ になっているものの俗称(だめ文字、駄目文字)
0x5cの \ は使用するフォントやロケールによりバックスラッシュまたは¥記号で表示されます。
ダメ文字を含む文字列やパス、ファイル名を処理する場合には文字化け、検索不可など様々な不具合が起きることがあります。

ダメ文字には ー ソ 十 表 など、使用頻度の高いものもあるので cp932を扱う場合には注意が必要です。
また広義には2byte目が 0x7c のパイプ文字 | になっている文字や、2byte目が正規表現などのメタ文字と重なる文字も含む場合もあります。
ダメ文字問題は正規表現をはじめとする様々な言語、システムで制御用のメタ文字として扱われる文字と同じバイト列が、SJISの漢字の2byte目に含まれていることにより起こります。
特に 0x5c や 0x7c は様々なシステムで制御文字として扱われるので問題が起こりやすくなります。

具体例

たとえば cygwin/GNU grepでは「表現」のように cp932のダメ文字 を含む文字列を、固定文字列(fgrep)では検索できますが、正規表現ではgrepできません。
表現」というダメ文字を含む日本語を検索しているつもりなのに、grep側からは正規表現で検索しているとみなされてしまうためです。

「表現」の cp932でのバイト列は 95 5c 8c bb です。
0x5c のバックスラッシュ(¥記号)は正規表現ではエスケープ文字なので 0x8c をエスケープ(通常文字扱い)して 95 8c bb というバイト列を探す事になりますが、これは当然見つかりません。

対処

2byte目が 0x5c のダメ文字についてはバックスラッシュ(¥記号)を付加して(表 → 表\) 回避する対処方法もあります。
QFixGrepでは全てのダメ文字への対策として適当な正規表現で置き換えてgrepしていますが、日本語の検索に関して言えば可能な限り正規表現を使用しない fgrep(固定文字列検索)を使用するべきです。

「ダメ文字」はSJIS固有の問題なので、utf-8等では関係ありません。
根本的な対策として、正規表現などが絡むファイルはutf-8等に変更するのが望ましいでしょう。
日本語版 Windowsのshellエンコーディングは(見かけ上) cp932なので、ファイル名でも同じ問題が起きる事があります。
このため日本語対応していないソフトを日本語版 Windowsで使用する場合、できるだけ日本語ファイル名を使用しない方が問題は起きにくくなります。
なお日本語版Windowsのshellの見かけ上は互換性のため cp932(Shift_JIS) になっていますが、内部的にはunicode化されています。

 2byte目が0x5c \ のダメ文字
Ы

 2byte目が0x7c | のダメ文字
л 忿
 ほぼ全てのダメ文字
 2byte目が下記のASCII文字
 @ [ \ ] ^ _ ` { | } ~


 ダメ文字の種類別に表にまとめてあります。
 「ダメ文字一覧表


Shift_JISとcp932


cp932(Microsoft定義のShift_JIS) と Shift_JIS とは厳密に言うと ~ など一部の文字コードの扱いが異なります。
このためダメ文字対策でcp932をUTF-8へ変換してから処理しようとした場合、以下の表の文字が含まれると変換後の文字が異なるため問題になることがあります。

UTF-8へ変換した場合に異なる文字
cp932
Windows
Linux
 0x8160 U+FF5E U+301C
 0x8161 U+2225 U+2016
 0x817C U+FF0D U+2212
 0x8191 U+FFE0 ¢ U+00A2
 0x8192 U+FFE1 £ U+00A3
 0x81CA U+FFE2 ¬ U+00AC
0x815C U+2015 U+2014
(注意) Vista以降での0x815CはU+2014

参考:「波ダッシュ」、「UTF-8→cp932変換表

サブページ (1): ダメ文字一覧表
Comments