[PHP-users 23014]Re: mb系使えない環境で全角 ー を含めた文字列の検索

Shuhei Tomita tomita @ zingy.or.jp
2004年 8月 18日 (水) 18:17:56 JST


On Wed, 18 Aug 2004 12:41:04 +0900
mooth959 @ infoseek.jp wrote:

冨田と申します。

> $k='キーワード;
> $fp='検索文字列';
> $sf=split($k,$fp);
> $hl=count($sf);
> if($hl>1){
> 	処理
> }
> 
> このとき強引ですが、日本語のキーワードに全角の横棒の”ー”が混じると
> 
> Warning: unexpected regex error (7) in /home/・・・
> 
> と出てしまいます。

$kの内容の文字コードは何でしょうか。おそらくEUCならこのような問題は起こ
らないので、SHIFT-JISではないかと思いますが、

$kの内容がShift-JISの文字列であるとすると、以下のように解釈することがで
きます。

キ   ー   ワ   ー   ド
834c 815b 838f 815b 8368    (16進表記)
 ? L  ? [  ? ?  ? [  ? h    (ASCIIコードに則って文字に変換)
                                ※ASCIIコードの範囲外の文字は?とする

正規表現の文法上、[と]は対でなければならないはずですので、

> Warning: unexpected regex error (7) in /home/・・・

というメッセージが表示されるのだと思います。
よって、[PHP-users 23007] [PHP-users 23006] で紹介してくださっている
splitのかわりにexplodeを使うか、$kをpreg_quote()する方法が良いと思います。

> $k='キーワード;
> $fp='検索文字列';
> $sf=split(base64_encode($k),base64_encode($fp));
> 
> としても、あるはずの文字に、マッチ(切り分け)自体しませんでした。

着想は良いのですが、Base64の特性上エンコードの際前後のバイトを考慮するの
で、たとえば、"aキ"と"キa"をエンコードした結果は全く異なる結果に
なります。

base64の際は、24bit(3byte)毎に4byteの文字列に変換しますので、前後に別の
文字が入っていると、全く別の文字に変換されます。

例:
"aキ"61834c = 01100001 10000011 01001100
              [ Y  ][  Y  ][  N  ][ M  ]

"キa"834c61 = 10000011 01001100 01100001
              [ g  ][  0  ][  x  ][ h  ]

この場合は、base64_encodeの代わりにbin2hexすると想定した結果になると思い
ます。

………………………………………………………………………………………………
		冨田 修平(Shuhei Tomita) tomita @ zingy.or.jp
………………………………………………………………………………………………



PHP-users メーリングリストの案内