新JavaScript入門  JavaScript,Neo-Generation  DOM  WSH  掲示板  表紙
8.文字列  10.フロー制御 
新JavaScript入門
9. 日本語の扱い
以下述べることは、全てShift-JISについてです。
もうすでに2バイト文字の扱いはネスケもIEと同様になって久しいので、 このページの記述はほとんど無視してよいと思われます。
NNとIEの違い
Netscape Navigator と Internet Explorer では2バイト文字の長さが違います。
    str1 = "カードキャプター";
    alert(""+str1.length);      //文字列の長さ
    str2 = str1.charAt(5);      //6番目の文字
    alert(str2);
 
上の例で、Netscape Navigator では文字列の長さは16 となりますが、Internet Explorer では8となります。 すなわち、2バイト文字を、Netscape Navigator では2文字、 Internet Explorer では1文字とカウントしているわけです。
そのため、日本語を処理するあらゆる場面で結果が違ってきます。 上の charAt の例では、 Netscape Navigator では "h" が、 Internet Explorer では "" が返ります。 "カードキャプター" の 6バイト目は、 "ド" のコードが 0x8368 のため 0x68、 すなわち "h" になります。
簡単な対処法
取り敢えず、2バイト文字ばかりならなんとかなります。 最初に2バイト文字が何文字とみなされるかを判定し、 それによって処理を分けます。 NNかIEかは、 navigator.appName では分かりますが、将来どちらかの仕様が変わることもありうるので、
    unitlength = "あ".length;
 
などとして判定しましょう。
そして例えば6文字目を取得したい時は、
    str2 = str1.substring(5 * unitlength, 6 * unitlength);
 
とします。
全角と半角の判別法
Netscape Navigator で文字の長さを取得する場合、 2バイト文字ばかりなら上の方法で対処できますが、 全角と半角が混ざっている場合はこれを判別する必要があります。
判別には escape を使います。 これは、引数の文字列を、アルファベットか数字ならそのまま、 その他なら"%xx"の形で返す関数です。 xx はASCIIコードの16進数表示です。 例を挙げると、
    str1 = escape("#");     // "%23"
    str2 = escape("a");     // "a"
    str3 = escape("あ");    // "%82%A0"
 
返り値の1バイト目が "%" で2バイト目が "8" , "9" , "E" , "F" なら 全角の1バイト目で、それ以外なら半角と判定できます。
    function test2(form) {
        var str = form.text1.value;
        var len = str.length;
        var n = 0;
        
        for(var i = 0; i < len; i++) {
            if(iszenkaku(str.charAt(i)))    //全角なら
                i++;                        //1バイト飛ばす
            n++;
        }
        alert(""+n);                        //文字数
    }
    
    //全角ならtrueを返す
    function iszenkaku(c) {
        var str = escape(c);
        
        if(str.charAt(0) != "%")
            return false;
        if(str.charAt(1) == "8")
            return true;
        else if(str.charAt(1) == "9")
            return true;
        else if(str.charAt(1) == "E")
            return true;
        else if(str.charAt(1) == "F")
            return true;
        else
            return false;
    }
 
テキストボックスに文字列を入力してボタンを押してください。 文字列の長さが表示されます。
Internet Explorer では escape の返り値が全角の場合違ってきます。
    str1 = escape("#");     // "%23"
    str2 = escape("a");     // "a"
    str3 = escape("あ");    // "%u3042"
 
全角の場合unicodeで返ってきますので、これを元に判別します。
    function test3(form) {
        var str = form.text1.value;
        var len = str.length;
        var n = 0;
        var i;
        
        for(i = 0; i < len; i++)
            n += is_ie_zenkaku(str.charAt(i)) ? 2 : 1;
        alert(""+n);
    }
    
    function is_ie_zenkaku(c) {
        return (escape(c).charAt(1) == "u");
    }
 
テキストボックスに文字列を入力してボタンを押してください。 文字列のバイト数が表示されます。
エスケープシーケンス
Netscape Navigator では、次のようなときに表示がおかしくなることがあります (Reloadするとならないらしい)。
    alert("ソt");
 
これは、"ソ" の2バイト目が 0x5C すなわち "\" のためです。 この直後に、"b"、"f"、"n"、"r"、"t"をつけてはいけません。 また、これで文字列を終わってはいけません。
この "ソ" と同様な文字には例えば次のようなものがあります。
    Ы\噂浬欺圭構蚕十申曾箪貼能表暴予禄兔喀媾彌拿杤歃
 
検索系メソッド
Netscape Navigator では、indexOflastIndexOfsplit の検索系のメソッドは使い物にならないこともあります。例えば、
    str1 = "モダン焼き";
    alert(""+str1.indexOf("_"));        // 3
    str2 = "ホットケーキ";
    alert(""+str2.lastIndexOf("P"));    // 7
    str3 = "攪拌機";
    arrtmp = str3.split("@");
    alert(""+arrtmp.length);            // 2
 
このような場合は、やはり1文字戻ってコードを調べましょう。 split の場合はそういうわけにはいきませんが。
Written 11/2/97
Modified 4/19/03
first, prev, next, exit