SJISでなくUTF8を使わなければならない理由

SJIS文字コードは2Byteで構成されていますが、特定の制御コードを含む文字は正規表現が使えません。

~$ ruby -e 'puts ("ア".."ン").to_a' > utf8.txt
~$ nkf -s < utf8.txt > sjis.txt

カタカナのSJISテキスト sjis.txtを作りました。各行の文字がgrepできるか見てみましょう。

~$ grep -n `nkf -s <<<ア` sjis.txt | nkf -w
1:ア
~$ grep -n `nkf -s <<<カ` sjis.txt | nkf -w
10:カ
~$ grep -n `nkf -s <<<サ` sjis.txt | nkf -w
20:サ
~$ grep -n `nkf -s <<<タ` sjis.txt | nkf -w
30:タ
~$ grep -n `nkf -s <<<ナ` sjis.txt | nkf -w
41:ナ
~$ 

上記の結果だと上手くいっているようです。問題となる文字で結果を見てみましょう。

~$ grep -n `nkf -s <<<ソ` sjis.txt | nkf -wgrep: 終端のバックスラッシュ
grep: 終端のバックスラッシュ
~$ 

失敗しました。”ソ”というカタカナをgrepできませんでした。

カタカナについて全部見てみます。

~$ for i in `cat utf8.txt`;do grep -n `nkf -s <<<$i` sjis.txt | nkf -w;done
(省略)
25:ズ
26:セ
grep: 無効な正規表現です
grep: 終端のバックスラッシュ
29:ゾ
30:タ
31:ダ
32:チ
(省略)

上記の番号の代わりにgrepエラーとなっている箇所が失敗箇所です。カタカナの「ゼ」、「ソ」が、上手くいかないようです。
もちろん正規表現を使わない場合はこれらの文字は検索できます。fgrepを使ってみます。

~$ for i in `cat utf8.txt`;do fgrep -n `nkf -s <<<$i` sjis.txt | nkf -w;done
1:ア
2:ィ
3:イ
4:ゥ
5:ウ
6:ェ
7:エ
8:ォ
9:オ
10:カ
11:ガ
12:キ
13:ギ
14:ク
15:グ
16:ケ
17:ゲ
18:コ
19:ゴ
20:サ
21:ザ
22:シ
23:ジ
24:ス
25:ズ
26:セ
27:ゼ
28:ソ
29:ゾ
30:タ
31:ダ
32:チ
33:ヂ
34:ッ
35:ツ
36:ヅ
37:テ
38:デ
39:ト
40:ド
41:ナ
42:ニ
43:ヌ
44:ネ
45:ノ
46:ハ
47:バ
48:パ
49:ヒ
50:ビ
51:ピ
52:フ
53:ブ
54:プ
55:ヘ
56:ベ
57:ペ
58:ホ
59:ボ
60:ポ
61:マ
62:ミ
63:ム
64:メ
65:モ
66:ャ
67:ヤ
68:ュ
69:ユ
70:ョ
71:ヨ
72:ラ
73:リ
74:ル
75:レ
76:ロ
77:ヮ
78:ワ
79:ヰ
80:ヱ
81:ヲ
82:ン
~$ 

次は漢字を見ていきましょう。漢字の場合は数が多いのでネストを少なくします。

~$ cnt=0;for i in `nkf -s < utf8.txt`;do
> ((cnt++));echo -n "$cnt "`nkf -w <<< $i`;(echo $i | grep $i ) |
> nkf -w;done 2>&1 | grep grep
56 予grep: 終端のバックスラッシュ
332 充grep: 無効な正規表現です
339 兌grep: 無効な正規表現です
344 兔grep: 終端のバックスラッシュ
569 十grep: 終端のバックスラッシュ
773 啓grep: 無効な正規表現です
782 喀grep: 終端のバックスラッシュ
791 喙grep: 無効な正規表現です
833 噂grep: 終端のバックスラッシュ
899 圭grep: 終端のバックスラッシュ
1044 夕grep: 無効な正規表現です
1162 媼grep: 無効な正規表現です
1164 媾grep: 終端のバックスラッシュ
1589 彈grep: 無効な正規表現です
1591 彌grep: 終端のバックスラッシュ
1906 房grep: 無効な正規表現です
1965 拏grep: 無効な正規表現です
1989 拿grep: 終端のバックスラッシュ
2045 措grep: 無効な正規表現です
2132 擬grep: 無効な正規表現です
2313 暴grep: 終端のバックスラッシュ
2343 曾grep: 終端のバックスラッシュ
2393 杣grep: 無効な正規表現です
2394 杤grep: 終端のバックスラッシュ
2513 梗grep: 無効な正規表現です
2634 構grep: 終端のバックスラッシュ
2744 欺grep: 終端のバックスラッシュ
2747 歃grep: 終端のバックスラッシュ
2748 歇grep: 無効な正規表現です
2935 浬grep: 終端のバックスラッシュ
2980 深grep: 無効な正規表現です
3137 濕grep: 無効な正規表現です
3145 濬grep: 終端のバックスラッシュ
3326 犱grep: 無効な正規表現です
3330 犾grep: 終端のバックスラッシュ
3491 甜grep: 無効な正規表現です
3504 申grep: 終端のバックスラッシュ
3511 畆grep: 無効な正規表現です
3521 畚grep: 終端のバックスラッシュ
3836 票grep: 無効な正規表現です
3843 禄grep: 終端のバックスラッシュ
3859 禺grep: 無効な正規表現です
3865 秉grep: 終端のバックスラッシュ
3972 端grep: 無効な正規表現です
4040 箪grep: 終端のバックスラッシュ
4157 納grep: 無効な正規表現です
4219 綣grep: 無効な正規表現です
4229 綵grep: 終端のバックスラッシュ
4310 纂grep: 無効な正規表現です
4314 纊grep: 終端のバックスラッシュ
4483 能grep: 終端のバックスラッシュ
4541 膽grep: 無効な正規表現です
4544 臀grep: 終端のバックスラッシュ
4882 藜grep: 無効な正規表現です
4889 藹grep: 終端のバックスラッシュ
4925 蚕grep: 終端のバックスラッシュ
5051 表grep: 終端のバックスラッシュ
5173 觴grep: 無効な正規表現です
5174 觸grep: 終端のバックスラッシュ
5397 貼grep: 終端のバックスラッシュ
5527 躰grep: 無効な正規表現です
5531 軆grep: 終端のバックスラッシュ
5962 鐔grep: 終端のバックスラッシュ
5965 鐚grep: 無効な正規表現です
6002 閏grep: 無効な正規表現です
6310 饅grep: 終端のバックスラッシュ
6311 饉grep: 無効な正規表現です
6385 骸grep: 無効な正規表現です
6584 鷦grep: 無効な正規表現です
6585 鷭grep: 終端のバックスラッシュ
6607 麓grep: 無効な正規表現です
~$ 

結構多いです。テキスト検索や整形をするなら、SJISのまま使わない方が無難ですね。

Leave a Reply

Your email address will not be published. Required fields are marked *

CAPTCHA