kazpgmの日記

『プログラム自動作成@自動生成』作成の日記

TOOL更新_半角、JISの第一、第二水準以外をエラーにするロジック。

TOOL更新_半角、JISの第一、第二水準以外をエラーにするロジック。
1.これはEthnaEthna_ActionFormクラスのcheckVendorCharメソッドを参考に作成した。EthnaEUC機種依存文字をチェックしている。自分はSJISで第一、第二水準以外をチェックした。「kaz PHPプログラム自動作成◎自動生成おたすけTOOL」はUTF-8なのでSJIS-WINにしてからチェックした。 <=JISは制御文字が入るらしくてハンドリングが難しいので同じ第一、第二水準を扱えるSJIS-WINを選んだ。

  • Ethnaからもらったのは、文字コードをヘキサにする方法。そのヘキサを判定する方法。・・・これがなかなかわからなかった。
  • SJISで第一、第二水準というのがJISの第一、第二水準の位置をシフトしたものだということをGoogleった結果わかった。そのコード位置(でも、見たWEBページによって微妙にちがうので。ちょっとずれているかも知れない。)もわかったので。このロジックとなった。echoをはずすとイメージがつかめると思う。

2.まず自PCで、”PHPsjisのまま”動かしたときのロジック。DOS画面で動かしたもの。

■test01.php
<?php
    $target = "①1鄯、a◆硃あ0ア郄熙";
    $rtn = chkJis1or2($target, "sjis-win");
if ($rtn == "") {
    print "OK文字です。" . "\n";
} else {
    print "これらの文字は使用できません。『" . $rtn . "』" . "\n";
}

    /**
     * JISの半角および、第1、2水準文字であることのチェック。<br>
     * @param    $target    検査する文字列
     * @enc        $enc    使用しているエンコード
     * @return    "":OK、以外:NG文字たち
     */
    function chkJIS1or2($target, $enc='utf-8'){
        $rtn = "";
        // UTF-8にしてから処理する。
        $target2 = mb_convert_encoding($target, 'utf-8', $enc);
        for($idx = 0; $idx < mb_strlen($target2, 'utf-8'); $idx++){
            $str0 = mb_substr($target2, $idx, 1, 'utf-8');
            // 1文字をSJISにする。
            $str = mb_convert_encoding($str0, "sjis-win", 'utf-8');
//echo "−−−−−−−−−−−−\n";
//echo mb_convert_encoding($str, $enc, "sjis-win") . "\n";
            //if (strlen($str) == 1) { // 1バイト文字
            if ((strlen(bin2hex($str)) / 2) == 1) { // 1バイト文字
                $c = ord($str{0});
            } else {
                $c = ord($str{0}); // 先頭1バイト
//echo "c=" . $c . "\n";
                $c2 = ord($str{1}); // 2バイト目
//echo "c2=" . $c2 . "\n";
                $c3 = $c * 0x100 + $c2; // 2バイト分の数値にする。
//echo "c3=" . $c3 . "\n";
//echo "dechex_c3=" . dechex($c3) . "\n";
                if ((($c3 >= 0x8140) && ($c3 <= 0x853D)) || // 2バイト文字
                    (($c3 >= 0x889F) && ($c3 <= 0x988F)) || // 第一水準
                    (($c3 >= 0x9890) && ($c3 <= 0x9FFF)) || // 第二水準
                    (($c3 >= 0xE040) && ($c3 <= 0xEAFF))) { // 第二水準
                } else {
                    $rtn .= mb_convert_encoding($str, $enc, "sjis-win");
//echo "機種依存文字など" . "\n";
                }
            }
        }
        return $rtn;
    }
?>

3.次は自PCで、”PHPUTF-8にして”動かしたときのロジック。「AppCheckUtil.java」に組み込んで自WEBから動かしたもの。画面から"①1鄯、a◆硃あ0ア郄熙"①1鄯、a◆硃あ0ア郄熙"と入力した。

    $rtn = AppCheckUtil::chkJis1or2($vars["corpnm"]);
if ($rtn == "") {
    print "OK文字です。" . "\n";
} else {
    print "これらの文字は使用できません。『" . $rtn . "』" . "\n";
}
exit;

class AppCheckUtil
{
・・・
    /**
     * JISの半角および、第1、2水準文字であることのチェック。<br>
     * @param    $target    検査する文字列
     * @return    "":OK、以外:NG文字たち
     */
    function chkJIS1or2($target){
        $rtn = "";
        for($idx = 0; $idx < mb_strlen($target, 'utf-8'); $idx++){
            $str0 = mb_substr($target, $idx, 1, 'utf-8');
            // 1文字をSJISにする。
            $str = mb_convert_encoding($str0, "sjis-win", 'utf-8');
//echo "−−−−−−−−−−−−\n";
//echo $str0 . "\n";
            //if (strlen($str) == 1) { // 1バイト文字
            if ((strlen(bin2hex($str)) / 2) == 1) { // 1バイト文字
                $c = ord($str{0});
            } else {
                $c = ord($str{0}); // 先頭1バイト
//echo "c=" . $c . "\n";
                $c2 = ord($str{1}); // 2バイト目
//echo "c2=" . $c2 . "\n";
                $c3 = $c * 0x100 + $c2; // 2バイト分の数値にする。
//echo "c3=" . $c3 . "\n";
//echo "dechex_c3=" . dechex($c3) . "\n";
                if ((($c3 >= 0x8140) && ($c3 <= 0x853D)) || // 2バイト文字
                    (($c3 >= 0x889F) && ($c3 <= 0x988F)) || // 第一水準
                    (($c3 >= 0x9890) && ($c3 <= 0x9FFF)) || // 第二水準
                    (($c3 >= 0xE040) && ($c3 <= 0xEAFF))) { // 第二水準
                } else {
                    $rtn .= $str0;
//echo "機種依存文字など" . "\n";
                }
            }
        }
        return $rtn;
    }

5/30 19:00-0:00 どこか間違いがあるかも知れない。が、とりあえず、最初の一歩。
5/31 20:30-21:00

『if (strlen($str) == 1) { // 1バイト文字』をやめて
『if ((strlen(bin2hex($str)) / 2) == 1) { // 1バイト文字』にした。

Googleったらこっちのほうがよさそうなので。
6/1 1:00-1:10 ”JISは制御文字が入るらしくてハンドリングが難しいので同じ第一、第二水準を扱えるSJIS-WINを選んだ。”を追記した。