堀北真希うさぎ
主な作品
堀北真希うさぎ:平成元年〜平成 3年頃のボシュロム製コンタクトレンズ『オプティマ』のCMを真似てコンタクトレンズをつける場面と仮想CM動画

ページ案内

仮名入力を補正するスクリプト。

仮名文字のみで入力すべきフォームに正しく入力されたかを確認し、不正な入力ならエラーとするスクリプトです。ひらがなや半角カナ文字は全角カナ文字に変換されます。

更に応用すれば、全角数字や全角アルファベットを半角にする事も出来ますが、長くなるので解説は控えさせて頂きます。

仮名入力を補正するスクリプト・目次。

まず言いたい事。

何度も書いておりますが、JAVAスクリプトは必須の技術ではないため、閲覧者の中には使えないように設定している方もいます。

文字のチェック及び補正はCGIでもやるようにして下さい

また、今回はサンプルが長くなり過ぎるので割愛しておりますが、本来はローマ字での入力にも対応すべきである事は言うまでもありません。

また、今回もシフトJISコードのウェブページで使う事を前提とします。

仮名入力を補正するスクリプトのサンプル。

以下のフォームは、カナ文字での氏名入力が必須となっております。

スクリプトを実行できる環境なら、何も入力しなかったりカナ文字以外の文字を入れて送信ボタンを押すと、エラーダイアログが開く筈です。

仮名文字のみで正常に入力している場合もダイアログが開いて、全角カナ文字に変換された文字列が表示されます。

認証入力
お名前(仮名文字で入力して下さい)

仮名入力を補正するスクリプトのソースとHTML文書での記述。

仮名入力を補正するスクリプト「CheckKanaEnter.js」は以下のようになっております。

//	半角カナ文字(濁点/半濁点つき)
hankana2='%uFF76%uFF9E%uFF77%uFF9E%uFF78%uFF9E%uFF79%uFF9E%uFF7A%uFF9E%uFF7B%uFF9E%uFF7C%uFF9E%uFF7D%uFF9E%uFF7E%uFF9E%uFF7F%uFF9E%uFF80%uFF9E%uFF81%uFF9E%uFF82%uFF9E%uFF83%uFF9E%uFF84%uFF9E%uFF8A%uFF9E%uFF8B%uFF9E%uFF8C%uFF9E%uFF8D%uFF9E%uFF8E%uFF9E%uFF8A%uFF9F%uFF8B%uFF9F%uFF8C%uFF9F%uFF8D%uFF9F%uFF8E%uFF9F%uFF73%uFF9E';
//	半角カナ文字(一字)
hankana1='%uFF71%uFF72%uFF73%uFF74%uFF75%uFF76%uFF77%uFF78%uFF79%uFF7A%uFF7B%uFF7C%uFF7D%uFF7E%uFF7F%uFF80%uFF81%uFF82%uFF83%uFF84%uFF85%uFF86%uFF87%uFF88%uFF89%uFF8A%uFF8B%uFF8C%uFF8D%uFF8E%uFF8F%uFF90%uFF91%uFF92%uFF93%uFF94%uFF95%uFF96%uFF97%uFF98%uFF99%uFF9A%uFF9B%uFF9C%uFF66%uFF9D%uFF67%uFF68%uFF69%uFF6A%uFF6B%uFF6F%uFF6C%uFF6D%uFF6E%uFF70%uFF64%uFF61%uFF65%uFF62%uFF63%uFF9E%uFF9F';

//	全角文字を一文字扱い出来ない旧式のブラウザの場合(シフトJISコード)
if ('あ'.length!=1) {
    hankana2='%B6%DE%B7%DE%B8%DE%B9%DE%BA%DE%BB%DE%BC%DE%BD%DE%BE%DE%BF%DE%C0%DE%C1%DE%C2%DE%C3%DE%C4%DE%CA%DE%CB%DE%CC%DE%CD%DE%CE%DE%CA%DF%CB%DF%CC%DF%CD%DF%CE%DF%B3%DE';
    hankana1='%B1%B2%B3%B4%B5%B6%B7%B8%B9%BA%BB%BC%BD%BE%BF%C0%C1%C2%C3%C4%C5%C6%C7%C8%C9%CA%CB%CC%CD%CE%CF%D0%D1%D2%D3%D4%D5%D6%D7%D8%D9%DA%DB%DC%A6%DD%A7%A8%A9%AA%AB%AF%AC%AD%AE%B0%A4%A1%A5%A2%A3%DE%DF';
    }
//    半角カナデータの取得。
hankana1=unescape(hankana1);
hankana2=unescape(hankana2);

//    ひらがな・全角カナ文字。
hiragana2='がぎぐげござじずぜぞだぢづでどばびぶべぼぱぴぷぺぽぶ';
hiragana1='あいうえおかきくけこさしすせそたちつてとなにぬねのはひふへほまみむめもやゆよらりるれろわをんぁぃぅぇぉっゃゅょー、。・「」゛゜ゎゐゑ';
katakana2='ガギグゲゴザジズゼゾダヂヅデドバビブベボパピプペポヴ';
katakana1='アイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワヲンァィゥェォッャュョー、。・「」゛゜ヮヰヱヵヶ';

//    カナ文字エラー
k_error='仮名文字以外は入力出来ません!';

function CheckKanaEnter() {
    s_len=0;
    i=document.forms[0].number.value;
    j='';

    //    全角文字を一文字と認識する環境。
    if ('あ'.length==1) {
        while (i!='') {
            k=i.substring(0,1);
            i=i.substring(1,i.length);
            //    全角カナならそのまま通す。
            m=katakana1.indexOf(k);
            if (m>-1) { j+=k; ++s_len; continue; }
            m=katakana2.indexOf(k);
            if (m>-1) { j+=k; ++s_len; continue; }
            //    ひらがな⇒全角カナへ。
            m=hiragana1.indexOf(k);
            if (m>-1) { j+=katakana1.substring(m,m+1); ++s_len; continue; }
            m=hiragana2.indexOf(k);
            if (m>-1) { j+=katakana2.substring(m,m+1); ++s_len; continue; }
            //    二文字半角カナ⇒全角カナへ。
            if (i!='') {
                m=hankana2.indexOf(k+i.substring(0,1));
                if (m>-1 && (m & 1)==0) {
                    m >>= 1;
                    j+=katakana2.substring(m,m+1); ++s_len; i=i.substring(1,i.length);
                    continue;
                    }
                }
            //    一文字半角カナ⇒全角カナへ。
            m=hankana1.indexOf(k);
            if (m>-1) { j+=katakana1.substring(m,m+1); ++s_len; continue; }
            //    その他の文字はエラー。
            window.alert(k_error); return(false);
            }
        }

    //    全角文字を一文字と認識しない環境。
    else {
        while (i!='') {
            k=i.substring(0,1);
            i=i.substring(1,i.length);
            if (i!='') {
                k1=k+i.substring(0,1); i1=i.substring(1,i.length);
                //    全角カナならそのまま通す。
                m=katakana1.indexOf(k1);
                if (m>-1 && (m & 1)==0) { j+=k1; ++s_len; i=i1; continue; }
                m=katakana2.indexOf(k1);
                if (m>-1 && (m & 1)==0) { j+=k1; ++s_len; i=i1; continue; }
                //    二文字半角カナ⇒全角カナへ。
                m=hankana2.indexOf(k1);
                if (m>-1 && (m & 1)==0) {
                    j+=katakana2.substring(m,m+2); ++s_len; i=i1; continue;
                    }
                //    ひらがな⇒全角カナへ。
                m=hiragana1.indexOf(k1);
                if (m>-1 && (m & 1)==0) { j+=katakana1.substring(m,m+2); ++s_len; i=i1; continue; }
                m=hiragana2.indexOf(k1);
                if (m>-1 && (m & 1)==0) { j+=katakana2.substring(m,m+2); ++s_len; i=i1; continue; }
                }
            //    一文字半角カナ⇒全角カナへ。
            m=hankana1.indexOf(k);
            if (m>-1) { m+=m; j+=katakana1.substring(m,m+2); ++s_len; continue; }
            //    その他の文字はエラー。
            window.alert(k_error); return(false);
            }
        }

    //    入力されているか?
    document.forms[0].number.value=j;    //    半角化された文字列をフォームに与える。
    if (s_len==0) {
        window.alert('仮名文字を入力して下さい。');
        return(false);
        }
    //    変換結果の表示(実際に応用する場合は下の一行は邪魔なので削除して下さい)。
    window.alert('変換結果 ['+j+']');
    return(true);
}

一方、HTML文書側には、以下のように記述されております。

<form action=" (略) " method="post" onsubmit="return(CheckKanaEnter());">
    <fieldset>
        <legend>認証入力</legend>
        <dl>
            <dt>お名前(仮名文字で入力して下さい)</dt>
            <dd><input type="text" name="number" size="16" /></dd>
            </dl>
        <ul>
            <li><input type="submit" value="送信" /></li>
            </ul>
        </fieldset>
    </form>

スクリプトの構成。(平成17年 8月21日 更新)

スクリプトの起動。(平成17年 8月21日 修正)

スクリプトはフォームの送信ボタンが押された時に起動します。

これは、<form>要素のonsubmit属性で実現します。

onsubmit属性は、当該<form>要素の送信手続きをイヴェントとして行なうイヴェントハンドラで、この属性値となるJAVAスクリプトが実行されます。

ここでは、CheckKanaEnter()函数を実行した結果をreturn文で返すというだけですが、その際にエラーを見出した場合はfalse値を返して送信をやめさせます。

スクリプトの処理。

スクリプトの処理は、お名前入力フィールドに入力されている文字列を取り出し、

  1. 半角カナ文字・ひらがなが混じっている場合は全角カナ文字に変換する(この文字に関しては正当な入力とする)
  2. 全角カナ文字以外の文字が入っている場合はエラーとする
  3. 文字列が空の場合はエラーとする

と言うものです。

以下、具体的な処理を解説して行きましょう。

0. 初期設定。

スクリプト冒頭は以下のようになります。

//	半角カナ文字(濁点/半濁点つき)
hankana2='%uFF76%uFF9E%uFF77%uFF9E%uFF78%uFF9E%uFF79%uFF9E%uFF7A%uFF9E%uFF7B%uFF9E%uFF7C%uFF9E%uFF7D%uFF9E%uFF7E%uFF9E%uFF7F%uFF9E%uFF80%uFF9E%uFF81%uFF9E%uFF82%uFF9E%uFF83%uFF9E%uFF84%uFF9E%uFF8A%uFF9E%uFF8B%uFF9E%uFF8C%uFF9E%uFF8D%uFF9E%uFF8E%uFF9E%uFF8A%uFF9F%uFF8B%uFF9F%uFF8C%uFF9F%uFF8D%uFF9F%uFF8E%uFF9F%uFF73%uFF9E';
//	半角カナ文字(一字)
hankana1='%uFF71%uFF72%uFF73%uFF74%uFF75%uFF76%uFF77%uFF78%uFF79%uFF7A%uFF7B%uFF7C%uFF7D%uFF7E%uFF7F%uFF80%uFF81%uFF82%uFF83%uFF84%uFF85%uFF86%uFF87%uFF88%uFF89%uFF8A%uFF8B%uFF8C%uFF8D%uFF8E%uFF8F%uFF90%uFF91%uFF92%uFF93%uFF94%uFF95%uFF96%uFF97%uFF98%uFF99%uFF9A%uFF9B%uFF9C%uFF66%uFF9D%uFF67%uFF68%uFF69%uFF6A%uFF6B%uFF6F%uFF6C%uFF6D%uFF6E%uFF70%uFF64%uFF61%uFF65%uFF62%uFF63%uFF9E%uFF9F';

//	全角文字を一文字扱い出来ない旧式のブラウザの場合(シフトJISコード)
if ('あ'.length!=1) {
    hankana2='%B6%DE%B7%DE%B8%DE%B9%DE%BA%DE%BB%DE%BC%DE%BD%DE%BE%DE%BF%DE%C0%DE%C1%DE%C2%DE%C3%DE%C4%DE%CA%DE%CB%DE%CC%DE%CD%DE%CE%DE%CA%DF%CB%DF%CC%DF%CD%DF%CE%DF%B3%DE';
    hankana1='%B1%B2%B3%B4%B5%B6%B7%B8%B9%BA%BB%BC%BD%BE%BF%C0%C1%C2%C3%C4%C5%C6%C7%C8%C9%CA%CB%CC%CD%CE%CF%D0%D1%D2%D3%D4%D5%D6%D7%D8%D9%DA%DB%DC%A6%DD%A7%A8%A9%AA%AB%AF%AC%AD%AE%B0%A4%A1%A5%A2%A3%DE%DF';
    }
//    半角カナデータの取得。
hankana1=unescape(hankana1);
hankana2=unescape(hankana2);

//    ひらがな・全角カナ文字。
hiragana2='がぎぐげござじずぜぞだぢづでどばびぶべぼぱぴぷぺぽぶ';
hiragana1='あいうえおかきくけこさしすせそたちつてとなにぬねのはひふへほまみむめもやゆよらりるれろわをんぁぃぅぇぉっゃゅょー、。・「」゛゜ゎゐゑ';
katakana2='ガギグゲゴザジズゼゾダヂヅデドバビブベボパピプペポヴ';
katakana1='アイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワヲンァィゥェォッャュョー、。・「」゛゜ヮヰヱヵヶ';

//    カナ文字エラー
k_error='仮名文字以外は入力出来ません!';

function CheckKanaEnter() {
    s_len=0;
    i=document.forms[0].number.value;
    j='';

半角カナ文字データの扱い。

まず、初めにお断りしておきますが、OSによっては半角カナ文字を含んだスクリプトを正常に受け容れる事が出来ない可能性があります。

このため、半角カナ文字に関しては、文字コード列を用意して、それを読込時に文字列に変換して利用する事にします。

JAVAスクリプトには文字コードを扱う函数は殆どありませんが、唯一組込関数のunescape()函数はURLエンコードで表現された文字列を処理出来るため、これを用いるものとします。

ところで、日本語文字に関してはいつも通りの問題点があります。

それは、全角文字を一文字扱いする環境では日本語文字は全てユニコードで扱われるのに対して、全角文字を一文字扱いしない環境では日本語文字は読込んだ時の文字コードそのものとなると言う事です。

つまり、日本語文字に関する扱いによって、半角カナ文字列の元となる文字コード列は異なると言う事になるのです。

そこで、まず全角文字を一文字扱いする環境向けにユニコードの文字コード列で表した半角カナ文字列を用意し、全角文字を一文字扱いしない環境である場合に限りシフトJISコードの文字コード列で表した半角カナ文字列に置き換えるものとします。

この結果得られた文字コード列をunescape()函数で生文字列に変換する事で処理に利用します。

尚、濁点・半濁点のついた半角カナ文字は一部濁点・半濁点込みで全角カナ文字に変換する事が出来る、すなわちその他の仮名文字と処理が異なるため、

それぞれ収めております。

ひらがな・全角カナ文字データの扱い。

ひらがなと全角カナ文字は、日本語に対応している環境であれば問題無く読込める筈ですので、そのまま生文字列で表しております。

CheckKanaEnter()函数の冒頭。

続いて、フォームのボタンが押された際に呼出される函数CheckKanaEnter()の本体が始まります。

まず、文字の長さをカウントする変数s_lenを0に初期化して、続いて、変数iにてフォームの会員番号入力欄の値を取得します。

変数jは全角数字を補正したあとの入力文字列が入ります。

エラー無しで判定が終わったら、最後に、入力フォームの当該欄に補正された文字列を入れる事で、CGI側の余計な負担(文字のチェックや全角数字の変換など)を減らせると言う訳です。

1. 入力文字の確認。

続いて、入力文字の確認を行ないます。

ここでの基本的な処理は、

と言うだけのものです。

ひらがなから全角カナ文字へは単純に変換出来ますが、半角カナ文字から全角カナ文字へはちょっと工夫が必要です。

それは、濁点・半濁点を伴う半角カナ文字は、二文字で一文字に纏められる場合があるからです。

この点を考慮して処理を纏めると、以下のようになります。

  1. 全角カナ文字なら無問題で通す。
  2. 濁点・半濁点を伴う半角カナ文字で、一文字に纏められるものであれば、対応する全角カナ文字に置き換える。
  3. ひらがなであれば、対応する全角カナ文字に置き換える。
  4. 最後に半角カナ文字であれば、対応する全角カナ文字に置き換える。
  5. 以上をいずれも満たせなかった場合は仮名文字では無いのでエラーとする。

尚、半角カナ文字のチェックについては、濁点・半濁点を伴うものは必ず一般の半角カナ文字処理より前に処理しなければいけません。

逆にしてしまうと濁点・半濁点があろうと無かろうと一般の半角カナ文字処理をパスしてしまうため、濁点・半濁点を纏める事が出来なくなってしまいます。

ところで、ブラウザによって日本語文字の扱いが異なっており、

と言う違いがあります(現行のブラウザは全て全角文字を一文字と見なしますが、旧いブラウザでは全角文字を二文字と見なすものがあります)。

このため、全角文字の扱いによって処理を変える必要があります。

全角文字を一文字と見なすブラウザの場合。

この場合、基本的には何も考えず頭から一文字づつ取出してチェックして行けばいいでしょう。

唯一、濁点・半濁点を伴う半角カナ文字に関してだけ、次の文字を先読みし、パスした場合に先読みした文字を捨てる事にします。

この処理は以下のようになります。

    //    全角文字を一文字と認識する環境。
    if ('あ'.length==1) {
        while (i!='') {
            k=i.substring(0,1);
            i=i.substring(1,i.length);
            //    全角カナならそのまま通す。
            m=katakana1.indexOf(k);
            if (m>-1) { j+=k; ++s_len; continue; }
            m=katakana2.indexOf(k);
            if (m>-1) { j+=k; ++s_len; continue; }
            //    ひらがな⇒全角カナへ。
            m=hiragana1.indexOf(k);
            if (m>-1) { j+=katakana1.substring(m,m+1); ++s_len; continue; }
            m=hiragana2.indexOf(k);
            if (m>-1) { j+=katakana2.substring(m,m+1); ++s_len; continue; }
            //    二文字半角カナ⇒全角カナへ。
            if (i!='') {
                m=hankana2.indexOf(k+i.substring(0,1));
                if (m>-1 && (m & 1)==0) {
                    m >>= 1;
                    j+=katakana2.substring(m,m+1); ++s_len; i=i.substring(1,i.length);
                    continue;
                    }
                }
            //    一文字半角カナ⇒全角カナへ。
            m=hankana1.indexOf(k);
            if (m>-1) { j+=katakana1.substring(m,m+1); ++s_len; continue; }
            //    その他の文字はエラー。
            window.alert(k_error); return(false);
            }
        }

処理の流れはスクリプトをご覧になれば大体分かるでしょうから詳細は割愛しますが、特に注意しておきたい事として、二文字半角カナ(濁点・半濁点つきの半角カナ文字)での処理のみ解説しておきます。

二文字半角カナを判定する時点では、後続文字が切出されるかどうかはまだ分からないので、後続文字を取出して連結した文字列をチェックする形にしております。

そして、その結果、パスした場合には、判定する文字列から後続文字列を切り落としております。

また、変数hankana2には半角カナ文字と半角濁点または半濁点が交互に並んでいるため、偶数番目の位置で見つかった場合のみにパスするものとします。

加えて対応する全角カナ文字を得るため、位置を入れている変数mを2で割っております。

全角文字を二文字と見なすブラウザの場合。

この場合の処理は以下のようになります。

    //    全角文字を一文字と認識しない環境。
    else {
        while (i!='') {
            k=i.substring(0,1);
            i=i.substring(1,i.length);
            if (i!='') {
                k1=k+i.substring(0,1); i1=i.substring(1,i.length);
                //    全角カナならそのまま通す。
                m=katakana1.indexOf(k1);
                if (m>-1 && (m & 1)==0) { j+=k1; ++s_len; i=i1; continue; }
                m=katakana2.indexOf(k1);
                if (m>-1 && (m & 1)==0) { j+=k1; ++s_len; i=i1; continue; }
                //    二文字半角カナ⇒全角カナへ。
                m=hankana2.indexOf(k1);
                if (m>-1 && (m & 1)==0) {
                    j+=katakana2.substring(m,m+2); ++s_len; i=i1; continue;
                    }
                //    ひらがな⇒全角カナへ。
                m=hiragana1.indexOf(k1);
                if (m>-1 && (m & 1)==0) { j+=katakana1.substring(m,m+2); ++s_len; i=i1; continue; }
                m=hiragana2.indexOf(k1);
                if (m>-1 && (m & 1)==0) { j+=katakana2.substring(m,m+2); ++s_len; i=i1; continue; }
                }
            //    一文字半角カナ⇒全角カナへ。
            m=hankana1.indexOf(k);
            if (m>-1) { m+=m; j+=katakana1.substring(m,m+2); ++s_len; continue; }
            //    その他の文字はエラー。
            window.alert(k_error); return(false);
            }
        }

この処理で注意したい事として、全角文字は常に二文字扱いになる事から、一文字半角カナ以外は後続文字も調べなければならないと言う事です。

しかも、面倒な事にそうしては行けない一文字半角カナのチェックもあります。

そこで、初めの段階で

それぞれ入れておき、一文字半角カナの判定以外では常にk1を調べ、パスしたら検索対象文字列を入れる変数iに後続文字も切出した後の状態となっている変数i1を代入すると言う事にしております。

2. 不正な文字が無い場合。

以上の判定を行なって、エラーが見出されなければ、入力文字は不当で無い事が分かります。

そこで、最後の処理を行ないます。

まず、ひらがな・半角カナ文字を変換した文字列をフォームに返します。
返さなくてもCGI側で同様の処理を行なえば良いのですが、それでは勿体無いのでこちらで補正したデータに書き変えてやります。
続いて、入力されているかどうかを判定します。
今回は一文字以上と決められておりますが、場合に依っては字数の範囲を決めている場合もあるでしょう(必要な方は各自やってみて下さい)。
最後に問題が無ければ正常終了する。
正常終了を通知して漸くフォームのデータがCGIにポストされます。

これらの処理は以下のようになります。

    //    入力されているか?
    document.forms[0].number.value=j;    //    半角化された文字列をフォームに与える。
    if (s_len==0) {
        window.alert('仮名文字を入力して下さい。');
        return(false);
        }
    //    変換結果の表示(実際に応用する場合は下の一行は邪魔なので削除して下さい)。
    window.alert('変換結果 ['+j+']');
    return(true);
}

この処理に関しての詳細は割愛します。

実際にこのスクリプトをご利用になる場合。

実用にするには、一部改造が必要です。

実際にこのスクリプトを改造して使いたいと言う方は、「// 変換結果の表示」とその次の行の

を削除して下さい。

これはサンプルスクリプトを実行させて得られた変換結果を分かり易く表示するためのものですので、実際には必要無いどころか邪魔になる筈のものだからです。

機能追加の余地があるでしょう。

ローマ字対応にする。

例えば、仮名文字だけでなく、ローマ字入力も受け容れるようにすれば更によくなるでしょう。

この場合、全角アルファベットも半角と同様に扱えるようにする必要がありますね。

詳しくは書きませんが、この機能を入れる場合、以下のようにすればいいと思われます。

全角アルファベットは、ひらがな・半角カナ文字変換の際に半角アルファベットに変換する
全角文字の扱いがブラウザによって異なるため、この段階で併せてやっておくと良いでしょう。

また、半角アルファベットも、大文字小文字を統一しておくと処理が楽になる筈です。

ローマ字変換は函数で記述しておく
全角文字の扱いによって二種類の処理のうちのどちらかを行なう事になっているため、ローマ字から仮名文字に変換する処理は双方で必要になるでしょう。

この処理は結構長くなると思われますので、函数に纏めておくとスクリプトが長くならずに済むでしょう。

仮名文字以外の文字も受付ける。

また、仮名文字に混じって数字を入れられるようにする必要があるかも知れません。

この場合も、全角数字を半角に変換する機能を追加すればいいでしょう。

しらぎくのウェブサイト作成入門サイトマップ



marguerite.site@gmail.com