- ベストアンサー
マルチバイト対応のsubstr
- マルチバイト対応のsubstrを使用してプログラミングをしていましたが、一部不具合が発生しています。
- substrのマルチバイト対応はニーズが高いと考えられ、既に実装例が存在する可能性があります。
- JScript・htaでアプリを作成しており、IE4以降で動作するJavaScriptのマルチバイト対応substrの動作するコードを教えてください。
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
No.1の補足から推測する限り、SJISと同じように全角を2バイトとカウントしてほしいということですよね。 Stringオブジェクトを拡張する形で作ってみました。多少苦労しましたが勉強になりました。 2バイト目が指定されてしまう時にはエラーにはせずに該当文字位置からカウントを開始する、 2バイト文字の1バイト目で終了する場合にはその文字を壊さずに返すという仕様にしてみました。 つくりがまだしょぼいのですがとりあえず動きます。どうでしょう? String.prototype.lengthB = function() { var len = 0; for (var i = 0; i < this.length; i++) { if (this.charAt(i).isMultibyte()) { len += 2; } else { len += 1; } } return len; } String.prototype.substrB = function() { var fromByte = arguments[0]; var retByte = arguments[1]; // 開始位置の検索 var len = 0; var i; for (i = 0; fromByte > len; i++) { if (this.charAt(i).isMultibyte()) { len += 2; } else { len += 1; } } var from = i; len = 0; var retLen = 0; while(retByte > len) { if (this.charAt(i).isMultibyte()) { len = len + 2; } else { len = len + 1; } retLen++; i++; } return this.substr(from, retLen); } String.prototype.isMultibyte = function() { var c = this.charCodeAt(0); // 半角の範囲 // Unicode : 0x0 ~ 0x80, 0xf8f0, 0xff61 ~ 0xff9f, 0xf8f1 ~ 0xf8f3 if ((c >= 0x0 && c <= 0x80) || (c == 0xf8f0) || (c >= 0xff61 && c <= 0xff9f) || (c >= 0xf8f1 && c <= 0xf8f3)) { return false; } else { return true; } }
その他の回答 (2)
- think49
- ベストアンサー率59% (285/482)
> バイト単位でカウントしてほしいという意味です。 以下、IE8,Firefox3で動作確認済みです。 # バイト範囲を誤るとエラーになる問題は妥協しました。 # 修正するなら、charAtを使用してデコードできない場合はエラーを返すのが妥当かと思います。 ---- <!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Strict//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd'> <html lang='ja' xml:lang='ja' xmlns='http://www.w3.org/1999/xhtml'> <head> <meta http-equiv='content-type' content='text/html; charset=utf-8' /> <meta http-equiv='content-style-type' content='text/css' /> <meta http-equiv='content-script-type' content='text/javascript' /> <meta name='author' content='think' /> <title>バイト単位で指定するsubstr</title> </head> <body> <script type='text/javascript'> (function(){ function substrByte(str, start, end){ str = encodeURIComponent(str); var i = 0, target = ''; str.match(/^/); // RegExp.rightContextの初期化 while(RegExp.rightContext){ RegExp.rightContext.match(/^(%[\da-z]{2}|.)/i); if(i >= start && i <= end){ target += RegExp.$1; } if(i == end){ break; } i++; } return decodeURIComponent(target); } var str = 'バイト単位で指定するsubstr'; var target = substrByte(str, 0, 2); // "バ" を抽出 (UTF-8は3バイト) document.body.appendChild(document.createTextNode(target)); })(); </script> </body> </html> ----
お礼
せっかく作っていただいたのですが以下の理由から使えませんでした。すみません。 ・日本語を3バイトとカウントしてしまう ・エラーがですぎ ・引数の意味がsubstrの仕様と異なる(slice,substring的な仕様になっている) でもありがとうございました。
- think49
- ベストアンサー率59% (285/482)
> それが、日本語が含まれた部分の切り出しでした…。 IE8で検証しましたが、substrでマルチバイト文字を切り出しできています。 substrとは別に原因があるのでは…。 <script type="text/javascript"> var str = 'マルチバイト対応のsubstr'; alert(str.substr(0,6)); // "マルチバイト" がalertされる </script>
お礼
ありがとうございました。
補足
すみません。説明不足でした。 バイト単位でカウントしてほしいという意味です。 ご提示の例では「マルチ」という結果を返してほしいということです。 もし回答可能でしたらよろしくお願いします。
お礼
いろいろ期待通りでした。完璧です。 ・日本語を2バイトとしてカウントする ・エラーが出ない柔軟なつくりになっている ・substrの仕様を踏襲している というかメソッドをStringに直接追加するあたりはむしろ期待以上です。 ありがとうございました。