Linux

全角スペースを半角スペースに変換する際に気をつけなきゃいけないこと(PHP&EUC-JPの場合)

PHP且つ文字コードがEUC-JPで、全角スペースを半角スペースに置き換える際のメモ。

検索サイトやWebサイトなどで、2つ以上の単語がスペースで繋いで入力された場合、
単語間の全角スペースを半角スペースに置換してるサイトが結構あったりする。
yahoo然り、gooも然り。

昔はUNIXの日本語環境だと、EUC-JPが標準だったみたいけど、LinuxではUTF-8が一般的になっている。

で、前置きが長くなりましたが、
(1)ユーザーが、テキストエリアに”特定の文字”を入力する
(2)システムが、全角スペースを検出して、半角スペースに置換する処理をする
(3)1.で全角スペースは入力されてないのに、全角スペースと判定されちゃう
というケースがあるので気をつけようぜ、という話。

1.の特定の文字というのは、前の文字のEUC文字コードが”A1”で終わり、後の文字のコードが”A1”で始まる組み合わせ。※EUC文字コードはコチラ

2.が、preg_replace(“/ +/”,” “,$carp);

という処理になっていて、例えば、$carp変数に”ファーストサーバ”という文字列が入ってくると、
“フ”+”璽好肇機璽”という2つの単語に分割されてしまう。

理由としては、”ァ”の文字コード”a5a1″と、”ー”の文字コード”a1bc”の組み合わせが、”a1a1″(全角スペース)と認識されてしまい、結果として、”フ”+”璽好肇機璽”になっちゃいます。

ググってみると、これでハマった人も何人かいるみたいで、preg_replace関数のバグだべ!っていう意見も出てたけども、
「文字コードがEUCで、文字列の全角スペースを半角スペースに置換する際は、preg_replace関数は使わないようにする。」が正解みたい。

EUC-JPで全角スペース→半角スペースの変換を行う場合は、
mb_convert_kana($carp,”s”,”EUC-JP”);
とすればおkです。※”s”は全角スペースを半角スペースに変換するオプション。

find,grep,locate

Linux検索コマンド find(xargs,exec)、grep、locate

grep → ファイル内から指定した文字列を含む行を検索する。
find → ディレクトリツリーの中から指定した文字列を含むファイルを検索する。

■seibulions.txtから「”aaaa”または”bbbb”」を含む行を検索。

grep “aaaa\|bbbb” seibulions.txt または
grep -e “aaaa” -e “bbbb” seibulions.txt

■seibulions.txtから「”aaaa”かつ”bbbb”」を含む行を検索。

grep “aaaa” seibulions.txt | grep “bbbb”

■/home/seibu配下のディレクトリツリーのテキストファイルの中から、”aaaa”を含むファイルを検索。
find /home/seibu/ -name \*.txt -print0 | xargs -0 grep “aaaa”

※xargsコマンドは、標準入力から引数を読み込み指定コマンドを実行するため、
findコマンドで見つかった全てのファイルのパスを’一度に’grepコマンドに渡してくれる。

※execを使った場合↓、’ファイル数分’grepコマンドが実行されるので時間がかかる。
find /home/seibu/ -name \*.txt -exec grep “aaaa” {} \;

※ファイル・ディレクトリ検索ならlocateコマンドの方が高速。

locate seibulions.txt と
find . -name ‘seibulions.txt’ -print は同意。

※FreeBSD 7.1でも、find -xargs、find -execともに使えるようです。