0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

toLocaleString() vs 正規表現 - 3桁区切りの最適解はどっち?

Posted at

Paizaの問題「大きな数の3桁区切り」で試行錯誤!
最初は正規表現で頑張ったけど、実は toLocaleString() の方がスマートだった!?
技術メモとしてまとめておくよ。


問題の概要

入力: 超デカい整数
出力: 3桁ごとにカンマを挿入した文字列

※位の小さい方から 3 けたごとにカンマ区切りで出力
※Nの桁数は 3 の倍数とは限らない

例:
入力: 12345678901234567890
出力: 12,345,678,901,234,567,890


解法①: 正規表現 + replace()

console.log(input.replace(/\B(?=(\d{3})+(?!\d))/g, ","));

解説
\B → 先頭を除く位置にマッチ(\b の逆)
(?=(\d{3})+(?!\d)) → 3桁ごとの数字のグループが一回以上繰り返されている、次が数字じゃない(=3桁数字グループの間)位置にマッチ。

.replace(..., ",") でカンマを挿入

メリット: 柔軟にカスタム可能
デメリット: 正規表現ミスるとバグりやすい(僕も最初、先頭にカンマ入る事故発生💀)


解法②: toLocaleString()

console.log(BigInt(input).toLocaleString());

解説
toLocaleString() → ロケール対応 で数値をフォーマット
BigInt 必須 →(Number 型では処理できない大きな数を扱いたい場合、BigInt を使う必要がある)

メリット: 簡潔 & 国際対応OK
デメリット: カスタマイズ性低め


まとめ

汎用性なら正規表現
お手軽 & 国際対応なら toLocaleString()

僕の失敗談と解決話!



おまけ

const rl = require('readline').createInterface({input: process.stdin});

rl.on('line',(input) => {

    function addCommas(num) {
    // 数字を文字列にしてから逆順にし、処理後に逆転させる
    let str = num.toString().split('').reverse().join('');
  
    let result = [];
  
    for (let i = 0; i < str.length; i++) {
    if (i > 0 && i % 3 === 0) {
      result.push(',');  // 3桁ごとにカンマを追加
    }
    result.push(str[i]);  // 現在の数字を追加
    }

    // 最後に文字列を逆順にして元に戻す
    return result.reverse().join('');
        
    }

    console.log(addCommas(input));  
    rl.close(); 
});
0
0
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?