千位分隔符的思考
英语里没有
万亿,只有百万(million)十亿(billion),千位分隔符就是这么产生的
1, 000 one thousand 一千
1, 000, 000 one million 一百万
1, 000, 000, 000 one billion 十亿
方案一: 正则
思路: 从个位往左数起,每三位前插入一个千位分隔符 , ,排除最开始的位置
String(Number).replace(/(\d)(?=(\d{3})+$)/g, "$1,");
String(1234567890).replace(/(\d)(?=(\d{3})+$)/g, "$1,");
// "1,234,567,890"说明:
g是表示全局匹配的修饰符,全局匹配指查找所有匹配而非在找到第一个匹配后停止。$是表示结尾的量词,如n$,匹配的是任何以n为结尾的字符串。\d是查找数字的元字符。n{X}是匹配包含 X 个 n 的序列的字符串的量词。+匹配前面的子表达式一次或多次;*匹配前面的子表达式0次或多次。?匹配前面的子表达式0次或1次,或指明一个非贪婪限定符。x(?=y)先行断言,匹配'x'仅仅当'x'后面跟着'y'match()String对象的方法,作用是找到一个或多个正则表达式的匹配。replace()String对象的方法,作用是替换与正则表达式匹配的子串。\B是表示匹配非单词边界的元字符,与其互为补集的元字符是\b,表示匹配单词边界。
方案二: toLocaleString
toLocaleString()方法返回一个该对象的字符串表示
覆盖 toLocaleString 的对象: Array: Array.prototype.toLocaleString()
Number: Number.prototype.toLocaleString()
Date: Date.prototype.toLocaleString()
Array.prototype.toLocaleString
概述: toLocaleString() 返回一个字符串 表示数组中的元素。数组中的元素将使用各自的 toLocaleString 方法转成字符串,这些字符串将使用一个特定语言环境的字符串(例如一个逗号 ", ")隔开。 语法: arr.toLocaleString([locales[,options]])
参数: locales (可选) 参数用于指定格式化对象时使用的语言环境,默认为当前环境的语言, 一般而言使用 en 或 zh 即可应付绝大多数情况。 MDN : 带有BCP47语言标记的 字符串或字符串数组 ,关于locales参数的形式与解释,请看Intl页面 options (可选) 一个可配置属性的 对象
[1, 2, 3, 4].toLocaleString()
// "1,2,3,4"
var prices = ['¥7', 500, 8123, 12];
prices.toLocaleString('ja-JP', {
style: 'currency',
currency: 'JPY'
});
// "¥7,¥500,¥8,123,¥12"至此, 将数组的 toLocaleString 方法理解为, 对数组每一项应用相应的 toLocaleString 方式, 然后返回组合的字符串, 即可.
Number.prototype.toLocaleString
其实不用传任何参数的时候, 千位分隔符的问题似乎就已经解决了.
const number = 123456789;
number.toLocaleString(); // 123,456,789
//对于中文场景下,toLocaleString('en-US')中的'en-US'理论上是可以缺省的,
//也就是直接(123456789).toLocaleString()也是可以得到123,456,789。
//但是如果你的产品可能海外用户使用,则保险起见,还是保留'en-US'。如果传参数的时候, 是什么样子呢 ? ( 以下主要针对 options 参数, locales 参数一般使用 zh .) style 表示格式化时使用的样式,默认值是 decimal 也就是纯数字,也可为 percent 百分比显示与 currency 货币显示。值为 currency 时必须同时指定 options 中的 currency 属性,否则报错。
const number = 2333333;
number.toLocaleString('zh', {
style: 'decimal'
}); //2,333,333
number.toLocaleString('zh', {
style: 'percent'
}); //233,333,300%
number.toLocaleString('zh', {
style: 'currency'
});
//Uncaught TypeError: Currency code is required with currency style.接下来的两个属性是 style 设为 currency 时才有用的,它们分别是 currency 与 currencyDisplay ,前者指定对应的货币,如 USD 、 EUR 与 CNY 等,不区分大小写。后者是货币符号的展示样式,默认值是 symbol ,即对应的符号,如 CNY 是 ¥ 。该属性的值也可以是 code 与 name
const number = 2333333;
number.toLocaleString('zh', {
style: 'currency',
currency: 'CNY'
});
//¥2,333,333.00
number.toLocaleString('zh', {
style: 'currency',
currency: 'cny',
currencyDisplay: 'code'
});
//CNY2,333,333.00
number.toLocaleString('zh', {
style: 'currency',
currency: 'cny',
currencyDisplay: 'name'
});
//2,333,333.00人民币最后是两组相当强大的属性,某些场景下能带来极大的便利。第一组是 minimumIntegerDigits 、 minimumFractionDigits 与 maximumFractionDigits ,用于指定整数至少位数 与 小数的至少和至多位数,不够则用0去凑。简单说,自动补0!
let number = 2333.3;
//整数至少5位
number.toLocaleString('zh', {
minimumIntegerDigits: 5
}); //02,333.3
//如果不想有分隔符,可以指定useGrouping为false
number.toLocaleString('zh', {
minimumIntegerDigits: 5,
useGrouping: false
});
//02333.3
//小数至少2位
number.toLocaleString('zh', {
minimumFractionDigits: 2,
useGrouping: false
}); //2333.30
//小数至多2位
number = 666.666
number.toLocaleString('zh', {
maximumFractionDigits: 2,
useGrouping: false
}); //666.67拓展:
ES2017引入了字符串补全长度的功能。如果某个字符串不够指定长度,会在头部或尾部补全。padStart()用于头部补全,padEnd()用于尾部补全。详情戳阮一峰大大.
另一组是 minimumSignificantDigits 与 maximumSignificantDigits ,用于控制 有效数字 位数,只要设置了这一组属性,第一组属性全部忽略不算
const number = 1234.5;
number.toLocaleString('zh', {
minimumSignificantDigits: 7,
useGrouping: false
}); //1234.500
number.toLocaleString('zh', {
maximumSignificantDigits: 4,
useGrouping: false
}); //1235Date.prototype.toLocaleString
直接进入到 options 参数的讲解: hour12 表示是使用十二小时制还是二十四小时制,默认值视 locales 而定
const date = new Date();
date.toLocaleString('zh', {
hour12: true
}); //"2018/5/9 下午3:20:07"
date.toLocaleString('zh', {
hour12: false
}); //"2018/5/9 15:20:07"
date.toLocaleString('en', {
hour12: true
}); //"5/9/2018, 3:20:07 PM"
date.toLocaleString('en', {
hour12: false
}); //"5/9/2018, 15:20:07"下面介绍其他属性 : weekday 、 era (时代)、 year 、 month 、 day 、 hour 、 minute 、 second timeZoneName
weekday 与 era 可选值: narrow 、 short 、 long
const date = new Date();
date.toLocaleString('en', {
weekday: 'narrow',
era: 'narrow'
}); //W A
date.toLocaleString('en', {
weekday: 'short',
era: 'short'
}); //Wed AD
date.toLocaleString('en', {
weekday: 'long',
era: 'long'
}); //Wednesday Anno DominitimeZoneName 可选值 short 、 long
const date = new Date();
date.toLocaleString('zh', {
timeZoneName: 'short'
}); // "2018/5/9 GMT+8 下午3:29:47"
date.toLocaleString('zh', {
timeZoneName: 'long'
}); // "2018/5/9 中国标准时间 下午3:29:47"剩下的属性,均可以取值为 numeric 与 2-digit ,简单说就是否仅用两位数字表示
const date = new Date();
date.toLocaleString('zh', {
year: 'numeric',
month: 'numeric',
day: 'numeric',
hour: 'numeric',
minute: 'numeric',
second: 'numeric',
}); //"2018/5/9 下午3:32:15"
date.toLocaleString('zh', {
year: '2-digit',
month: '2-digit',
day: '2-digit',
hour: '2-digit',
minute: '2-digit',
second: '2-digit'
}); //"18/05/09 下午3:32:15"
//比较奇怪的是 hour、minute 与 second 三个属性,无论设置为何值,表现都是一样的??month 属性, 除去 numeric 与 2-digit 外,它额外多三个属性,分别是 narrow 、 short 与 long
const date = new Date();
date.toLocaleString('zh', {
month: 'long'
}); // "五月"
date.toLocaleString('zh', {
month: 'short'
}); // "5月"
date.toLocaleString('zh', {
month: 'narrow'
}); // "5"