PHPのmb_strwidth()とmb_strimwidth()をJavaScriptで実装する

f:id:y_d:20120801003512p:plain

PHPのmb_strwidth()関数とmb_strimwidth()関数をJavaScriptで移植してみました。あまり動作確認してませんが、どうやらそれっぽく動いているようなので公開します。

mb_strwidth()

int mb_strwidth ( string $str [, string $encoding ] )

文字列 str の幅を返します。
マルチバイト文字は、通常はシングルバイト文字の倍の幅となります。

元となるPHPのインターフェースは第二引数までありますが、今回移植したものには第二引数$encodingはありません(UTF-8以外の動作確認してませんが、多分文字コードにかかわらずうまく動くとおもいます)。

PHPで次のコードを実行すると、16になります。

<?php
var_dump(mb_strwidth("abcアイウあいうえお")); //int(16)
?>

JavaScript版で同様のコードを実行しても16になります。

console.log(mb_strwidth("abcアイウあいうえお")); // 16

mb_strimwidth()

string mb_strimwidth ( string $str , int $start , int $width [, string $trimmarker [, string $encoding ]] )

文字列 str を指定した幅 width で丸めます。

こちらも一番最後の引数$encodingはありませんが、それ以外はPHP版と同じです。

PHPで次のコードを実行すると「Hello W...」と出力されます。

<?php
var_dump(mb_strimwidth("Hello World", 0, 10, "...")); //string(10) "Hello W..."
?>

JavaScript版でも同じく「Hello W...」となります。

console.log(mb_strimwidth("Hello World", 0, 10, "...")); //Hello W... 

ソース

下記のソースをコピペすれば使えます。

;(function(ns){
	/**
	 * mb_strwidth
	 * @param String
	 * @return int
	 * @see http://php.net/manual/ja/function.mb-strwidth.php
	 */
	var mb_strwidth = function(str){
		var i=0,l=str.length,c='',length=0;
		for(;i<l;i++){
			c=str.charCodeAt(i);
			if(0x0000<=c&&c<=0x0019){
				length += 0;
			}else if(0x0020<=c&&c<=0x1FFF){
				length += 1;
			}else if(0x2000<=c&&c<=0xFF60){
				length += 2;
			}else if(0xFF61<=c&&c<=0xFF9F){
				length += 1;
			}else if(0xFFA0<=c){
				length += 2;
			}
		}
		return length;
	};
	
	/**
	 * mb_strimwidth
	 * @param String
	 * @param int
	 * @param int
	 * @param String
	 * @return String
	 * @see http://www.php.net/manual/ja/function.mb-strimwidth.php
	 */
	var mb_strimwidth = function(str,start,width,trimmarker){
		if(typeof trimmarker === 'undefined') trimmarker='';
		var trimmakerWidth = mb_strwidth(trimmarker),i=start,l=str.length,trimmedLength=0,trimmedStr='';
		for(;i<l;i++){
			var charCode=str.charCodeAt(i),c=str.charAt(i),charWidth=mb_strwidth(c),next=str.charAt(i+1),nextWidth=mb_strwidth(next);
			trimmedLength += charWidth;
			trimmedStr += c;
			if(trimmedLength+trimmakerWidth+nextWidth>width){
				trimmedStr += trimmarker;
				break;
			}
		}
		return trimmedStr;
	};
	ns.mb_strwidth   = mb_strwidth;
	ns.mb_strimwidth = mb_strimwidth;
})(window);


//こんな感じで使えます
console.log(mb_strwidth("abcアイウあいうえお")); // 16

gistにもあります。
https://gist.github.com/3217440

以上です。