PHPと日本語文字列
日本語圏で使うWebアプリをPHPで組み立てる上では、日本語処理は欠かせません。では、どのように処理していけばいいのでしょうか。
文字コードはUTF-8がおすすめ
まず、内部処理で使う文字コードとしては、UTF-8で進めるべきでしょう(特定の文字コードを要求するシステムとのやり取りの際には、入出力時に変換すれば済みます)。シフトJISやEUCでは文字の切れ目がわかりづらく、いわゆる「ダメ文字」問題など、妙なところにヒットする事故が発生しがちです。これに対して、UTF-8の場合は
- 1バイト文字…0x00-0x7F(0b0xxxxxxx)
- 複数バイト文字の2バイト目以降…0x80-0xBF(0b10xxxxxx)
- 2バイト文字の1バイト目…0xC21-0xDF(0b110xxxxx)
- 3バイト文字の1バイト目…0xE0-0xEF(0b1110xxxx)
- 4バイト文字の1バイト目…0xF0-0xF72(0b11110xxx)
というように、「1バイト目」と「それ以降」が別に定義してあるため、単純なバイト比較による検索でも文字の切れ目を誤って誤爆することはありません(正規化の加減で「同じ」に見える文字がヒットしないことはありますが、それとは別問題です)。
さらに、この特徴があることで、シングルバイトを意識した関数を使える場面も増えますし、正規表現のPCREもUTF-8モードで使うことができます。
PCREとUTF-8
PHPのPCRE正規表現には、UTF-8指定子のu
があります。UTF-8指定子を付けずに正規表現を書くと、UTF-8の1文字はそのままバイト列として認識されます。
そのままで問題なく動く場面も多いですが、.
は1バイトにヒットしますし、2バイト以上の文字をキャラクタクラスの[]
に入れてしまうと、バイト単位でどれかという意味になってしまい、正しくヒットしなくなります。よほど速度にシビアな場面を除けば、/regex/u
というように、UTF-8指定を付けるようにしておいたほうがいいでしょう。
なお、u
付きの正規表現で処理をかけると、検索対象がUTF-8として正しいかどうかのチェックをして、おかしなコードならヒットさせずにFALSE
を返します。これを利用して、preg_match('//u', $target)
と空の正規表現と照合させることで、UTF-8としての整合性チェックに使えます。
UTF-8での文字列関数
上に述べたように、UTF-8の文字列にバイト単位の比較で検索をかけても、文字の切れ目を誤ってヒットしてしまうことは起きないので、引数を文字列単位で扱うような関数(explode
、sprintf
、str_replace
、strpos
など)は、UTF-8文字列に対しても問題なく適用することができます(strpos
はバイト数単位で位置を返しますが)。
一方で、文字列をバイト単位で扱う関数の場合、UTF-8の文字が途中で切れることになるため、正しく動作しません。例えば、trim
で全角空白を除かせることはできませんし、str_shuffle
はバイト単位でシャッフルして、(たいていの場合)正しくないUTF-8としてしまいます。strtr
では、2引数であればUTF-8でも問題ないですが、3引数の場合はASCII内の文字を、同じくASCII内の文字に置き換えるのにしか使えません(が、入力文字列自体はUTF-8混じりでも問題ありません)。
Author And Source
この問題について(PHPと日本語文字列), 我々は、より多くの情報をここで見つけました https://qiita.com/jkr_2255/items/a55d984f46e87b2a6c93著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .