在金融、報表、數據展示等場景中,數字添加千分位分隔符(如 1,234,567)是常見需求。Java 的正則表達式支持零寬斷言,讓我們能用極其簡潔的一行代碼完成這項任務。
"1234567890".replaceAll("(?<=\\d)(?=(?:\\d{3})+$)", ",");
// 結果:1,234,567,890
(?<=\\d) - 正向後顧斷言:匹配位置前面必須是一個數字
(?=(?:\\d{3})+$) - 正向先行斷言:匹配位置後面必須是若干組「3個數字」直到字符串結尾
組合含義:在「前面是數字」且「後面是若干個3位數字組」的位置插入逗號
// 基本整數
"1234567890".replaceAll("(?<=\\d)(?=(?:\\d{3})+$)", ","); // 1,234,567,890
// 不足 3 位不加逗號
"123".replaceAll("(?<=\\d)(?=(?:\\d{3})+$)", ","); // 123
"1234".replaceAll("(?<=\\d)(?=(?:\\d{3})+$)", ","); // 1,234
// 包含小數點(需先分離整數部分)
String num = "1234567.89";
String[] parts = num.split("\\.");
String formatted = parts[0].replaceAll("(?<=\\d)(?=(?:\\d{3})+$)", ",");
if (parts.length > 1) formatted += "." + parts[1];
// 結果:1,234,567.89
| 方案 | 代碼複雜度 | 性能 | 適用場景 |
|---|---|---|---|
| 正則零寬斷言 | 極低(一行) | 中等 | 簡單快速格式化 |
| DecimalFormat | 低 | 高 | 生產環境、複雜格式 |
| StringBuilder 手動插入 | 高 | 最高 | 極高性能要求 |
| NumberFormat.getNumberInstance() | 低 | 高 | 國際化、本地化格式 |
雖然正則方案極其優雅,但生產環境建議使用 DecimalFormat 或 NumberFormat,原因:
// 生產環境推薦寫法
DecimalFormat df = new DecimalFormat("#,###.##");
String result = df.format(1234567.89); // 1,234,567.89