ものすごく車輪の再発明な気もするが、備忘録としておいておく。
Perl クックブックのレシピ 2.16 によると、表題のことを行う関数は次のように表せる。
sub commify {
my $text = reverse $_[0];
$text =~ s/(\d\d\d)(?=\d)(?!\d*\.)/$1,/g;
return scalar reverse $text;
}
これを Javascript で表すと次のようになる。
String.prototype.reverse=function(){return this.split('').reverse().join('')};
Number.prototype.commify=function(){return this.toString().reverse().replace(/(\d\d\d)(?=\d)(?!\d*\.)/g,'$1,').reverse()};
// 使用例
alert( (123456789).commify() ); // 「123,456,789」
alert( (-123456789).commify() ); // 「-123,456,789」
alert( (1234.56789).commify() ); // 「1,234.56789」
まず、Javascript では文字列を反転させる関数がないので String.prototype.reverse() としてそれを定義している(1 行目)。そして、複雑な 2 行目を解説すると……
Number.prototype.commify = function() {
var str = this.toString(); // 数値を文字列化
str = str.reverse(); // 反転
str = str.replace( /(\d\d\d)(?=\d)(?!\d*\.)/g, '$1,' );
// コンマを挿入する
str = str.reverse(); // もう一度反転
return str;
};
s/
(\d\d\d) # 3 文字の数字
(?=\d) # 次の文字は数字
(?!\d*\.) # 小数部分ではない
/
$1,
/gx
このようになる。肝は正規表現の 4 行目で、小数部分にコンマを挿入しないようにしている。これがなければもうちょっと単純になるんだけどね。
