BLOG ENTRY

マルチバイト文字Unicodeで正規表現preg_match()[PHP]

php

確証はないけどPHPの正規表現でおもしろいことを発見してしまった。
EUC-JPのunicode下二桁がF5~FEの文字はpreg_match()がマッチしないっぽい。

例えば、サーバ文字コードはEUC-JPで、
[php]
<?php
function chkString($str) {
$pattern = "/^[亜-熙]*$/";
if (preg_match($pattern, $str) > 0) {
return true;
}
return false;
}
$str = "歯";
$result = chkString($str);
[/php]

trueが返ってきそうなもんだがfalseが返ってきてくれます。

正規表現のパターン箇所をこんな感じに変えても同じく。
[php]
$pattern = "^[\xA1\xA0-\xF4\xF6]*$";
[/php]

この文字に限らず、EUC-JPunicode下二桁がF5~FEの文字だと同じようにスカってしまいます。。。

なので、こんなコードを書いてみた。
かなり体育会系で汗くさいコードですが、一応意図した動作をしてくれた。

[php]
<?php
function chkString($str) {
$start16 = "A1A0";
$end16 = "F4A6";
$start10 = hexdec($start16);
$end10 = hexdec($end16);

for ($i = 0; $i < mb_strlen($str); $i++) {
$char = mb_substr($str, $i, 1);
$charUnicode = bin2hex($char);
$char10 = hexdec($charUnicode);
if ($char10 < $start10 || $char10 > $end10) {
return false;
}
}
return true;
}
$str = "歯";
$result = chkString($str);
[/php]

まず比較対象の16進数Unicodeを10進数に変換して、対象文字数分ループしながら
1文字ずつ、判別文字列をUnicode16進数に変換して10進数に変換して比較。

preg_matchは意図した通りに動かなかったので、
他の正規表現関数も同じかなと決め込んでたけどmb_ereg()を使えば意図した動作をしてくれた。

[php]
<?php
function chkString($str) {
$pattern = "^[\xA1\xA0-\xF4\xF6]*$";
if (mb_ereg($pattern, $str) > 0) {
return true;
}
return false;
}
$str = "歯";
$result = chkString($str);
[/php]

これは$resultにちゃんとtrueが返ってきました。

preg_match・・・不思議だ。。

WRITE COMMENT


(required)


(required)


(required)

MENU

veltica creative of twitter