How to get the length of Japanese characters in Javascript?

后端 未结 2 1090
名媛妹妹
名媛妹妹 2021-01-13 01:05

I have an ASP Classic page with SHIFT_JIS charset. The meta tag under the page\'s head section is like this:



        
2条回答
  •  花落未央
    2021-01-13 01:58

    For example, the character 测 has a SHIFT_JIS length of 8 characters, but Javascript is only recognizing it as one character, probably because of the Unicode encoding

    Let's be clear: 测, U+6D4B (Han Character 'measure, estimate, conjecture') is a single character. When you encode it to a particular encoding like Shift-JIS, it may very well become multiple bytes.

    In general JavaScript doesn't make encoding tables available so you can't find out how many bytes a character will take up. If you really need to, you have to carry around enough data to work it out yourself. For example, if you assume that the input contains only characters that are valid in Shift-JIS, this function would work out how many bytes are needed by keeping a list of all the characters that are a single byte, and assuming every other character takes two bytes:

    function getShiftJISByteLength(s) {
        return s.replace(/[^\x00-\x80。「」、・ヲァィゥェォャュョッーアイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワン ゙ ゚]/g, 'xx').length;
    }
    

    However, there are no 8-byte sequences in Shift-JIS, and the character 测 is not available in Shift-JIS at all. (It's a Chinese character not used in Japan.)

    Why you might be thinking it constitutes an 8-byte sequence is this: when a browser can't submit a character in a form, because it does not exist in the target charset, it replaces it with an HTML character reference: in this case . This is a lossy mangling: you can't tell whether the user typed literally or . And if you are displaying the submitted content as then that means you are forgetting to HTML-encode your output, which probably means your application is highly vulnerable to cross-site scripting.

    The only sensible answer is to use UTF-8 instead of Shift-JIS. UTF-8 can happily encode 测, or any other character, without having to resort to broken HTML character references. If you need to store content limited by encoded byte length in your database, there is a sneaky hack you can use to get the number of UTF-8 bytes in a string:

    function getUTF8ByteLength(s) {
        return unescape(encodeURIComponent(s)).length;
    }
    

    although probably it would be better to store native Unicode strings in the database so that the length limit refers to actual characters and not bytes in some encoding.

提交回复
热议问题