JavaScript千位分隔符/字符串格式化

135

Javascript中是否有用于格式化数字和字符串的函数?

我正在寻找一种方法来为字符串或数字添加千位分隔符...(类似于C#中的String.Format)


http://bytes.com/topic/c-sharp/answers/248039-formatcurrency-equiv - bevacqua
我认为你会在这里找到所需的内容 :) https://dev59.com/YXRB5IYBdhLWcg3weXOX - Jad
如何在JavaScript中打印带有逗号的数字作为千位分隔符:https://dev59.com/P3E85IYBdhLWcg3wMAfc - Adriano
15个回答

239

原始答案中引用的参考文献是错误的。实际上有一个内置函数可以实现此功能,正如kaiser在下面所建议的一样:toLocaleString

因此,您可以这样做:

(1234567.89).toLocaleString('en')              // for numeric input
parseFloat("1234567.89").toLocaleString('en')  // for string input

下面实现的函数也可以工作,但其实并不必要。
(我曾经在2010年时想着或许会发现它是必要的,但事实上并不是这样。根据这个更可靠的参考文献,toLocaleString 从 ECMAScript 3rd Edition [1999] 开始就成为了标准的一部分,这意味着它应该被支持到 IE 5.5。)
原始答案 根据这个参考文献,JavaScript 没有内置的添加逗号到数字的函数。但该页面包括了一个自己编写代码的示例:
function addCommas(nStr) {
    nStr += '';
    var x = nStr.split('.');
    var x1 = x[0];
    var x2 = x.length > 1 ? '.' + x[1] : '';
    var rgx = /(\d+)(\d{3})/;
    while (rgx.test(x1)) {
            x1 = x1.replace(rgx, '$1' + ',' + '$2');
    }
    return x1 + x2;
}

编辑: 要将逗号分隔的字符串转换为数字,您可以使用以下方法:

parseFloat("1,234,567.89".replace(/,/g,''))

1
非常感激!但是我该如何将这个带有逗号的字符串转换为数字? - LostLord
这个函数在大于100,000的数字时会出错。 - DevZer0
1
@DevZer0 不,它不是这样的。 - Tallboy
当toLocaleString方法无法满足您的需求时,原始答案可以为您提供更多控制。 - Mauricio Gracia Gutierrez
4
使用(1234567).toLocaleString().replace(/,/g," ",)将千位间隔转化为空格。 - Fanky
显示剩余4条评论

137

如果涉及到本地化千位分隔符、分隔符和小数点分隔符,请按照以下方式进行:

// --> numObj.toLocaleString( [locales [, options] ] )
parseInt( number ).toLocaleString();

你可以使用多个选项(甚至带有回退的本地化):

number = 123456.7089;

result  = parseInt( number ).toLocaleString() + "<br>";
result += number.toLocaleString( 'de-DE' ) + "<br>";
result += number.toLocaleString( 'ar-EG' ) + "<br>";
result += number.toLocaleString( 'ja-JP', { 
  style           : 'currency',
  currency        : 'JPY',
  currencyDisplay : 'symbol',
  useGrouping     : true
} ) + "<br>";
result += number.toLocaleString( [ 'jav', 'en' ], { 
  localeMatcher            : 'lookup',
  style                    : 'decimal',
  minimumIntegerDigits     : 2,
  minimumFractionDigits    : 2,
  maximumFractionDigits    : 3,
  minimumSignificantDigits : 2,
  maximumSignificantDigits : 3
} ) + "<br>";

var el = document.getElementById( 'result' );
el.innerHTML = result;
<div id="result"></div>

MDN信息页面上查看详细信息。

编辑:评论者@I like Serena 补充如下内容:

为了支持非英语环境的浏览器,但仍想使用英语格式,请使用value.toLocaleString('en')。 对于浮点数也适用。


1
这不包括浮点数...你可以将parseInt更改为parseFloat,但如果yourInt =“100,12”(逗号作为小数分隔符),则会失败。这可以通过replace(“,”,“。”)来修复..但是在“1.000,12”中仍然会失败。所以...有时你必须重新发明轮子。 https://dev59.com/P3E85IYBdhLWcg3wMAfc#2901298 - neiker
1
这样会更合适:Number(yourNumberOrString).toLocaleString() - Jonathan
2
为了支持非英语区域的浏览器,但仍然想使用英语格式,请使用 value.toLocaleString('en')。对于浮点数也适用。 - Klaas van Aarsen
1
@Serhiog.Lazin 究竟在Safari上有什么问题(在哪个操作系统和哪个版本中)? - kaiser
4
了解,对于印度的数字格式如7,77,77,777,可以使用value.toLocaleString('en-IN') - Makesh
显示剩余3条评论

48

根据ECMAScript2018的更改,使用后行支持进行更新。
为了向后兼容,请向下滚动以查看原始解决方案。

正则表达式可以用于处理存储为字符串的大数值,非常有用。

const format = num => 
    String(num).replace(/(?<!\..*)(\d)(?=(?:\d{3})+(?:\.|$))/g, '$1,')

;[
    format(100),                           // "100"
    format(1000),                          // "1,000"
    format(1e10),                          // "10,000,000,000"  
    format(1000.001001),                   // "1,000.001001"
    format('100000000000000.001001001001') // "100,000,000,000,000.001001001001
]
    .forEach(n => console.log(n))

» 正则表达式详细解释 (regex101.com) 流程图


这个原始答案可能不是必需的,但可以用于向后兼容。

尝试使用单个正则表达式(没有回调)处理此问题,我的当前能力在JavaScript中缺少负向回溯...然而,这里有另一种简洁的替代方法,在大多数情况下都有效 - 通过忽略出现在句点索引之后的匹配来考虑任何小数点。

const format = num => {
    const n = String(num),
          p = n.indexOf('.')
    return n.replace(
        /\d(?=(?:\d{3})+(?:\.|$))/g,
        (m, i) => p < 0 || i < p ? `${m},` : m
    )
}

;[
    format(100),                           // "100"
    format(1000),                          // "1,000"
    format(1e10),                          // "10,000,000,000"  
    format(1000.001001),                   // "1,000.001001"
    format('100000000000000.001001001001') // "100,000,000,000,000.001001001001
]
    .forEach(n => console.log(n))

» 正则表达式详细解释 (regex101.com)

流程图


这个语法图是在regex101.com上创建的吗? - Gerold Broser
带小数的数字会发生什么? - Emiliano
1
@Emissary 感谢你的提示。是的,这个问题出现在 React Native 0.59 / Android 上,它使用了相对较旧的 JavaScriptCore (JSC) 版本。我们更新到 React Native 0.60+ 后再试一次,因为它包含了 JSC 的更新。 - Joshua Pinter
在Edge浏览器中无法工作,它会显示“意外的量词”。 - Mahendra Jella
@LeadDeveloper 它在最新版本(79/80)中有效 - 实际上只是在最近一个月左右引入的。也许尝试强制浏览器更新? - Emissary
显示剩余2条评论

11

有一个不错的jQuery数字插件:https://github.com/teamdf/jquery-number

它允许您以所需格式更改任何数字,包括小数位和千分位分隔符选项:

$.number(12345.4556, 2);          // -> 12,345.46
$.number(12345.4556, 3, ',', ' ') // -> 12 345,456

你可以直接将它放在输入框中,这样更加方便,使用和上面相同的选项:

$("input").number(true, 2);

或者,您可以使用选择器来应用于整个DOM元素集:

$('span.number').number(true, 2);

最佳解决方案,我个人认为。 - Michal
1
我认为不必要,用800行代码来增加一个新文件需求就像用榴弹轰杀一只蚂蚁。 - Emiliano

6

1
哈哈哈,试试这个: var n = 4720 console.log(n.toLocaleString()) 它不会起作用。 - Emiliano

6
我使用这个:
function numberWithCommas(number) {
    return number.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
}

source: link


'123452343267.0505'.replace(/\B(?=(\d{3})+(?!\d))/g, ","); "123,452,343,267.0,505" - 注意小数点后面的最后一个逗号。 - hippietrail

5
// thousand separates a digit-only string using commas
// by element:  onkeyup = "ThousandSeparate(this)"
// by ID:       onkeyup = "ThousandSeparate('txt1','lbl1')"
function ThousandSeparate()
{
    if (arguments.length == 1)
    {
        var V = arguments[0].value;
        V = V.replace(/,/g,'');
        var R = new RegExp('(-?[0-9]+)([0-9]{3})'); 
        while(R.test(V))
        {
            V = V.replace(R, '$1,$2');
        }
        arguments[0].value = V;
    }
    else  if ( arguments.length == 2)
    {
        var V = document.getElementById(arguments[0]).value;
        var R = new RegExp('(-?[0-9]+)([0-9]{3})'); 
        while(R.test(V))
        {
            V = V.replace(R, '$1,$2');
        }
        document.getElementById(arguments[1]).innerHTML = V;
    }
    else return false;
}   

3
你可以使用JavaScript。下面是代码,它只会接受数字和一个小数点。

这是JavaScript代码:

<script >

            function FormatCurrency(ctrl) {
                //Check if arrow keys are pressed - we want to allow navigation around textbox using arrow keys
                if (event.keyCode == 37 || event.keyCode == 38 || event.keyCode == 39 || event.keyCode == 40) {
                    return;
                }

                var val = ctrl.value;

                val = val.replace(/,/g, "")
                ctrl.value = "";
                val += '';
                x = val.split('.');
                x1 = x[0];
                x2 = x.length > 1 ? '.' + x[1] : '';

                var rgx = /(\d+)(\d{3})/;

                while (rgx.test(x1)) {
                    x1 = x1.replace(rgx, '$1' + ',' + '$2');
                }

                ctrl.value = x1 + x2;
            }

            function CheckNumeric() {
                return event.keyCode >= 48 && event.keyCode <= 57 || event.keyCode == 46;
            }

  </script>

HTML

<input type="text" onkeypress="return CheckNumeric()" onkeyup="FormatCurrency(this)" />

JSFIDDLE演示


3
number = 123456.7089;
result = parseInt( number ).toLocaleString() + "<br>";
result = number.toLocaleString( 'pt-BR' ) + "<br>";

var el = document.getElementById( 'result' );
el.innerHTML = result;

<div id="result"></div>

6
你能否添加一些描述,让提问者和其他人能够理解这段代码是如何解决问题的。谢谢。 - Punit Gajjar
请尝试使用介于1000和9999之间的数字。 - Emiliano

3

您只需要真正做的就是这个

123000.9123.toLocaleString()
//result will be "123,000.912"

不幸的是,这取决于您的平台。有些平台有一个toLocaleString(),它不会添加逗号,或者缺少标准中的其他功能。检查toLocaleString是否存在很容易,但检查其是否符合标准却不容易。 - hippietrail
请尝试使用介于1000和9999之间的数字。 - Emiliano

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接