JavaScript'te virgül içeren bir sayıyı binlerce ayırıcı olarak yazdırma


1781

Binlerce ayırıcı olarak virgülle JavaScript'te bir tam sayı yazdırmaya çalışıyorum . Örneğin, 1234567 sayısını "1,234,567" olarak göstermek istiyorum. Bunu nasıl yapabilirim?

İşte nasıl yapıyorum:

function numberWithCommas(x) {
    x = x.toString();
    var pattern = /(-?\d+)(\d{3})/;
    while (pattern.test(x))
        x = x.replace(pattern, "$1,$2");
    return x;
}

Bunu yapmanın daha basit veya daha zarif bir yolu var mı? Şamandıralarla da çalışması iyi olurdu, ancak bu gerekli değildir. Noktalar ve virgül arasında karar vermek için bölgeye özgü olması gerekmez.


156
Number (x) .toLocaleString ()
Boffin

@Boffin bu giriş türü numarası için çalışmıyor (virgül nedeniyle) - kabul edilen cevapta virgülle nokta değiştirebiliriz ve giriş türü numarası çalışır
Vitaly Zdanevich

48
2016'da Safari'de Number.prototype.toLocaleString hala çalışmadığını belirtmek gerekir . Sayıyı gerçekten biçimlendirmek yerine, sadece döndürür, hiçbir hata atılmaz. Bunun bir sonucu olarak bugün en büyük facepalm sahip ... #goodworkApple
aendrew

Ancak, iOS safarisinde çalışıyor gibi görünüyor.
Tim

toLocaleString tutarsız ve kullanılmamalıdır. Örneğin - Firefox'ta bu 1.234 döndürür, ancak IE'de bu ondalık sayılar ekler: 1.234.00
Bort

Yanıtlar:


2833

Fikri Kerry'nin cevabından kullandım, ancak basitçe özel amacım için basit bir şey aradığım için basitleştirdim. İşte yaptığım şey:

function numberWithCommas(x) {
    return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
}


Normal ifade 2 ileriye dönük iddia kullanır:

  • dizedeki, arkasından arka arkaya 3 basamağın katı olan herhangi bir noktayı aramak için pozitif bir nokta,
  • noktanın yalnızca 3 basamaktan tam olarak katının olduğundan emin olmak için olumsuz bir iddia. Değiştirme ifadesi virgül koyar.

Örneğin, 123456789.01iletirseniz, pozitif iddia 7'nin solundaki her nokta ile eşleşir (çünkü 7893 basamağın 678katları olduğu için, 3 basamağın katlarıdır 567, vb.). Olumsuz iddia, 3 basamaktan çoğunun ondan sonra herhangi bir basamak olmadığını kontrol eder. 789ondan sonra bir nokta var, bu yüzden tam olarak 3 hanenin katıdır, bu yüzden virgül oraya gider. 6783 basamağın katlarıdır, ancak bir 9art arda sahiptir, bu nedenle bu 3 basamak 4 grubun bir parçasıdır ve virgül oraya gitmez. Benzer şekilde 567. 4567896 rakamıdır, bu sayı 3'ün katıdır, bu yüzden virgül bundan önce gelir. 3456783'ün katlarıdır, ancak 9bundan sonra bir virgül vardır, bu yüzden hiçbir virgül oraya gitmez. Ve bunun gibi. \B normal ifadenin dizenin başına virgül koymasını engeller.

@ neu-rah , ondalık noktadan sonra 3'ten fazla basamak varsa, bu işlevin istenmeyen yerlere virgül eklediğini belirtti. Bu bir sorunsa, bu işlevi kullanabilirsiniz:

function numberWithCommas(x) {
    var parts = x.toString().split(".");
    parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ",");
    return parts.join(".");
}

@ tjcrowder , artık JavaScript'in arkasına ( destek bilgisi ) sahip olduğuna, normal ifadenin kendisinde çözülebileceğine dikkat çekti :

function numberWithCommas(x) {
    return x.toString().replace(/\B(?<!\.\d*)(?=(\d{3})+(?!\d))/g, ",");
}

(?<!\.\d*)eşleşmenin önüne .sıfır veya daha fazla basamak gelemeyeceğini söyleyen negatif bir görünümdür . Olumsuz bakış , en azından V8'de splitve joinçözeltisinden ( karşılaştırma ) daha hızlıdır .


21
Çok güzel, ondalık noktadan sonra 3'ten fazla yeri olan sayılarla ilgili problemleri olduğunu fark ettiniz.
Eric Petroelje

60
numberWithCommas (12345.6789) deneyin -> "12,345.6,789" i bunu sevmiyorum
neu rah

4
Kesirler ile iyi çalışmaz, ondalık noktadan sonra virgül istemezdik
Mugen

30
'.' problem '123456789.01234'.replace (/ \ B (? = (? = \ d * \.) (\ d {3}) + (?! \ d)) / g,' _ ')
Dmitrij Golubev

8
@DmitrijGolubev Tamsayılar için çalışmaz. Belki ondalık noktayı zorlamak çözüm olacaktır.
Vlad

1809

Kimsenin Number.prototype.toLocaleString'den bahsetmediğine şaşırdım . JavaScript 1.5'te (1999'da tanıtıldı) uygulandığından, temel olarak tüm büyük tarayıcılarda desteklenir.

var n = 34523453.345
n.toLocaleString()
"34,523,453.345"

Ayrıca Intl dahil edilerek v0.12 itibariyle Node.js'de çalışır

Bu işlevin bir sayı değil bir dize döndürdüğüne dikkat edin.

Farklı bir şey istiyorsanız, Numeral.js ilginç olabilir.


17
@csigrist İyi puanlar, ama göründüğü kadar kötü değil. Hız tarayıcıya bağlıdır. FF veya Opera'da iyi performans gösterir. Yine de Chrome'da berbat. Sıfırlara gelince: var number = 123456.000; number.toLocaleString('en-US', {minimumFractionDigits: 2}); "123,456.00"Bu seçenekler FF veya Safari'de çalışmaz.
uKolka

22
Bağlama bağlı olarak performans farkı bir sorun olabilir veya olmayabilir. 1000 sonuçtan oluşan dev bir tablo için kullanılırsa, daha önemli olacaktır, ancak sadece tek bir değer için kullanılıyorsa, fark göz ardı edilebilir. Ancak avantajı, yerel ayarlara duyarlı olması, bu nedenle Avrupa'daki birisinin 34.523.453.345 veya 34 523 453.345'i görmesi . Bu, birçok ülkeden ziyaretçilerin bulunduğu bir sitede daha önemli olacaktır.
T Nguyen

6
Muhteşem. Sonunda yerli işlev ile bir cevap. Ve dahası, bu farklı ayırıcılar ile farklı ülkelerde düzgün bir şekilde görüntülenir (Çek Cumhuriyeti'nde yazıyoruz X XXX XXX,YYY).
Tomáš Zato - Monica'yı geri yükle

22
Google'cuların için Güncelleme: toLocaleStringaracılığı v0.12 itibariyle node.js çalışır Intl dahil .
srobinson

8
@MSC Eğer denemelisiniz parseInt("1234567", 10).toLocaleString('en-US', {minimumFractionDigits: 2})veya new Number("1234567").toLocaleString('en-US', {minimumFractionDigits: 2})onun yerine. Bu bir sayı üzerinde değil, bir dizede kullandığınız için çalışmıyor.
uKolka

244
var number = 1234567890; // Example number to be converted

J Javascript'in maksimum tamsayı değeri 9007199254740991 olduğunu unutmayın.


toLocaleString :

number.toLocaleString(); // "1,234,567,890"

// A more complex example: 
var number2 = 1234.56789; // floating point example
number2.toLocaleString(undefined, {maximumFractionDigits:2}) // "1,234.57"


NumberFormat ( Safari desteklenmez):

var nf = new Intl.NumberFormat();
nf.format(number); // "1,234,567,890"

Ne kontrol ettiğimden (en azından Firefox) ikisi de performans açısından aşağı yukarı aynı.


6
NumberFormat, orada uygulayanlar için Safari'de desteklenmez.
marcovega

6
toLocaleString de safari'de desteklenmiyor
Deepak Banka

3
Tarayıcı desteği her zaman bağlandığım her MDN sayfasının altında belirtilir.
vsync

5
toLocaleStringsafari üzerinde temel çalışmalar, seçenekler yok
dandavis

3
toLocaleStringÇözelti muhtemelen bu yüzden, istenen yerel içermelidir toLocaleString("en"), çünkü İngiliz model kullandığı virgül. Bununla birlikte, toLocaleString()Fransa'da yerel ayar göstergesi olmadan çalıştırılırsa, virgül yerine nokta verir, çünkü binleri yerel olarak ayırmak için kullanılır.
Mike 'Pomax' Kamermans

112

Ben phpjs.org 's number_format () kullanmanızı öneririz

function number_format(number, decimals, dec_point, thousands_sep) {
    // http://kevin.vanzonneveld.net
    // +   original by: Jonas Raoni Soares Silva (http://www.jsfromhell.com)
    // +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +     bugfix by: Michael White (http://getsprink.com)
    // +     bugfix by: Benjamin Lupton
    // +     bugfix by: Allan Jensen (http://www.winternet.no)
    // +    revised by: Jonas Raoni Soares Silva (http://www.jsfromhell.com)
    // +     bugfix by: Howard Yeend
    // +    revised by: Luke Smith (http://lucassmith.name)
    // +     bugfix by: Diogo Resende
    // +     bugfix by: Rival
    // +      input by: Kheang Hok Chin (http://www.distantia.ca/)
    // +   improved by: davook
    // +   improved by: Brett Zamir (http://brett-zamir.me)
    // +      input by: Jay Klehr
    // +   improved by: Brett Zamir (http://brett-zamir.me)
    // +      input by: Amir Habibi (http://www.residence-mixte.com/)
    // +     bugfix by: Brett Zamir (http://brett-zamir.me)
    // +   improved by: Theriault
    // +   improved by: Drew Noakes
    // *     example 1: number_format(1234.56);
    // *     returns 1: '1,235'
    // *     example 2: number_format(1234.56, 2, ',', ' ');
    // *     returns 2: '1 234,56'
    // *     example 3: number_format(1234.5678, 2, '.', '');
    // *     returns 3: '1234.57'
    // *     example 4: number_format(67, 2, ',', '.');
    // *     returns 4: '67,00'
    // *     example 5: number_format(1000);
    // *     returns 5: '1,000'
    // *     example 6: number_format(67.311, 2);
    // *     returns 6: '67.31'
    // *     example 7: number_format(1000.55, 1);
    // *     returns 7: '1,000.6'
    // *     example 8: number_format(67000, 5, ',', '.');
    // *     returns 8: '67.000,00000'
    // *     example 9: number_format(0.9, 0);
    // *     returns 9: '1'
    // *    example 10: number_format('1.20', 2);
    // *    returns 10: '1.20'
    // *    example 11: number_format('1.20', 4);
    // *    returns 11: '1.2000'
    // *    example 12: number_format('1.2000', 3);
    // *    returns 12: '1.200'
    var n = !isFinite(+number) ? 0 : +number, 
        prec = !isFinite(+decimals) ? 0 : Math.abs(decimals),
        sep = (typeof thousands_sep === 'undefined') ? ',' : thousands_sep,
        dec = (typeof dec_point === 'undefined') ? '.' : dec_point,
        toFixedFix = function (n, prec) {
            // Fix for IE parseFloat(0.55).toFixed(0) = 0;
            var k = Math.pow(10, prec);
            return Math.round(n * k) / k;
        },
        s = (prec ? toFixedFix(n, prec) : Math.round(n)).toString().split('.');
    if (s[0].length > 3) {
        s[0] = s[0].replace(/\B(?=(?:\d{3})+(?!\d))/g, sep);
    }
    if ((s[1] || '').length < prec) {
        s[1] = s[1] || '';
        s[1] += new Array(prec - s[1].length + 1).join('0');
    }
    return s.join(dec);
}

GÜNCELLEME 02/13/14

İnsanlar bunun beklendiği gibi çalışmadığını bildiriyor, bu yüzden otomatik testler içeren bir JS Fiddle yaptım .

Güncelleme 26/11/2017

İşte biraz değiştirilmiş çıktıya sahip bir Stack Snippet olarak:

function number_format(number, decimals, dec_point, thousands_sep) {
    // http://kevin.vanzonneveld.net
    // +   original by: Jonas Raoni Soares Silva (http://www.jsfromhell.com)
    // +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +     bugfix by: Michael White (http://getsprink.com)
    // +     bugfix by: Benjamin Lupton
    // +     bugfix by: Allan Jensen (http://www.winternet.no)
    // +    revised by: Jonas Raoni Soares Silva (http://www.jsfromhell.com)
    // +     bugfix by: Howard Yeend
    // +    revised by: Luke Smith (http://lucassmith.name)
    // +     bugfix by: Diogo Resende
    // +     bugfix by: Rival
    // +      input by: Kheang Hok Chin (http://www.distantia.ca/)
    // +   improved by: davook
    // +   improved by: Brett Zamir (http://brett-zamir.me)
    // +      input by: Jay Klehr
    // +   improved by: Brett Zamir (http://brett-zamir.me)
    // +      input by: Amir Habibi (http://www.residence-mixte.com/)
    // +     bugfix by: Brett Zamir (http://brett-zamir.me)
    // +   improved by: Theriault
    // +   improved by: Drew Noakes
    // *     example 1: number_format(1234.56);
    // *     returns 1: '1,235'
    // *     example 2: number_format(1234.56, 2, ',', ' ');
    // *     returns 2: '1 234,56'
    // *     example 3: number_format(1234.5678, 2, '.', '');
    // *     returns 3: '1234.57'
    // *     example 4: number_format(67, 2, ',', '.');
    // *     returns 4: '67,00'
    // *     example 5: number_format(1000);
    // *     returns 5: '1,000'
    // *     example 6: number_format(67.311, 2);
    // *     returns 6: '67.31'
    // *     example 7: number_format(1000.55, 1);
    // *     returns 7: '1,000.6'
    // *     example 8: number_format(67000, 5, ',', '.');
    // *     returns 8: '67.000,00000'
    // *     example 9: number_format(0.9, 0);
    // *     returns 9: '1'
    // *    example 10: number_format('1.20', 2);
    // *    returns 10: '1.20'
    // *    example 11: number_format('1.20', 4);
    // *    returns 11: '1.2000'
    // *    example 12: number_format('1.2000', 3);
    // *    returns 12: '1.200'
    var n = !isFinite(+number) ? 0 : +number, 
        prec = !isFinite(+decimals) ? 0 : Math.abs(decimals),
        sep = (typeof thousands_sep === 'undefined') ? ',' : thousands_sep,
        dec = (typeof dec_point === 'undefined') ? '.' : dec_point,
        toFixedFix = function (n, prec) {
            // Fix for IE parseFloat(0.55).toFixed(0) = 0;
            var k = Math.pow(10, prec);
            return Math.round(n * k) / k;
        },
        s = (prec ? toFixedFix(n, prec) : Math.round(n)).toString().split('.');
    if (s[0].length > 3) {
        s[0] = s[0].replace(/\B(?=(?:\d{3})+(?!\d))/g, sep);
    }
    if ((s[1] || '').length < prec) {
        s[1] = s[1] || '';
        s[1] += new Array(prec - s[1].length + 1).join('0');
    }
    return s.join(dec);
}

var exampleNumber = 1;
function test(expected, number, decimals, dec_point, thousands_sep)
{
    var actual = number_format(number, decimals, dec_point, thousands_sep);
    console.log(
        'Test case ' + exampleNumber + ': ' +
        '(decimals: ' + (typeof decimals === 'undefined' ? '(default)' : decimals) +
        ', dec_point: "' + (typeof dec_point === 'undefined' ? '(default)' : dec_point) + '"' +
        ', thousands_sep: "' + (typeof thousands_sep === 'undefined' ? '(default)' : thousands_sep) + '")'
    );
    console.log('  => ' + (actual === expected ? 'Passed' : 'FAILED') + ', got "' + actual + '", expected "' + expected + '".');
    exampleNumber++;
}

test('1,235',    1234.56);
test('1 234,56', 1234.56, 2, ',', ' ');
test('1234.57',  1234.5678, 2, '.', '');
test('67,00',    67, 2, ',', '.');
test('1,000',    1000);
test('67.31',    67.311, 2);
test('1,000.6',  1000.55, 1);
test('67.000,00000', 67000, 5, ',', '.');
test('1',        0.9, 0);
test('1.20',     '1.20', 2);
test('1.2000',   '1.20', 4);
test('1.200',    '1.2000', 3);
.as-console-wrapper {
  max-height: 100% !important;
}


İşaretlediğimden değil, ama insanların işe yaradığından inanıyorlar. Durduğu gibi bazı testlerinizin bile işe yaramadığını görüyorum.
Andrew S

3
@Andrew S - Yalnızca 1 kişi işaretledi. İşe yarıyor, birçok kez kendi kodumda kullandım. Ayrıca benim kodum (ne de testlerim) değil, iyi bilinen bir site olan siteye başvurdum. Belki de güncellenmiş bir sürümü var) baktığınız kod 3 yaşında olduğu için.
Kerry Jones

13
@ernix - Operatör JavaScript istedi, ben verdiğim cevap ise JavaScript. Bu, bir PHP işlevinin JavaScript yorumudur.
Kerry Jones

2
@ernix - OP'nin verdiği örnekle tam olarak beklendiği gibi çalışır. Görebilmek için bir keman koydum.
Kerry Jones

4
@ernix - Tamam ama nokta yapmasıdır tam OP ne istedi. Başka bir siteden (benim tarafımdan korunmuyor ve bunu daha önce belirtmiştim) ve uygun değişkenleri verirken tam olarak belirtildiği gibi çalışıyor. Bunun bir hata olduğuna inanıyorsanız, phpjs.org ile iletişime geçin veya güncellenmiş bir sürümüne sahip olup olmadığına bakın.
Kerry Jones

75

Bu @ mikez302'nin cevabının bir varyasyonudur, ancak ondalık sayıları desteklemek için modifiye edilmiştir (@ neu-rah'ın "12,345.6789" yerine "12,345.6789" yerine bu sayı

function numberWithCommas(n) {
    var parts=n.toString().split(".");
    return parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ",") + (parts[1] ? "." + parts[1] : "");
}


67
function formatNumber (num) {
    return num.toString().replace(/(\d)(?=(\d{3})+(?!\d))/g, "$1,")
}

print(formatNumber(2665));      // 2,665
print(formatNumber(102665));    // 102,665
print(formatNumber(111102665)); // 111,102,665

Cevabımın bunu yapmaması için ne yapar? Normal ifade biraz farklı görünüyor ama aynı şeyi yapması gerektiği anlaşılıyor.
Elias Zamaria

8
daha kısa :)
Tutankhamen

4
Bu zarif. Tam aradığım şey.
geleneksel

4
Gönderen blog.tompawlak.org/number-currency-formatting-javascript ? Bilinen sorun: formatNumber (0.123456) = 0.123.456 JS'de lookbehind'in olmaması, zarif bir normal ifadeyle düzeltilmesini zorlaştırıyor.
Vlad

1
123456789.123456789.toString (). Değiştir (/ (\ d) (? = (\ D {3}) + \.) / G, '$ 1,') => 123,456,789.12345679
kenberkeley

53

Normal ifadeyi kullanma

function toCommas(value) {
    return value.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
}
console.log(toCommas(123456789)); // 123,456,789

console.log(toCommas(1234567890)); // 1,234,567,890
console.log(toCommas(1234)); // 1,234

ToLocaleString () kullanma

var number = 123456.789;

// request a currency format
console.log(number.toLocaleString('de-DE', { style: 'currency', currency: 'EUR' }));
// → 123.456,79 €

// the Japanese yen doesn't use a minor unit
console.log(number.toLocaleString('ja-JP', { style: 'currency', currency: 'JPY' }))
// → ¥123,457

// limit to three significant digits
console.log(number.toLocaleString('en-IN', { maximumSignificantDigits: 3 }));
// → 1,23,000

ref MDN: Number.prototype.toLocaleString ()

Intl.NumberFormat () öğesini kullanma

var number = 123456.789;

console.log(new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(number));
// expected output: "123.456,79 €"

// the Japanese yen doesn't use a minor unit
console.log(new Intl.NumberFormat('ja-JP', { style: 'currency', currency: 'JPY' }).format(number));
// expected output: "¥123,457"

// limit to three significant digits
console.log(new Intl.NumberFormat('en-IN', { maximumSignificantDigits: 3 }).format(number));

// expected output: "1,23,000"

ref Intl.NumberFormat

BURADA DEMO

<script type="text/javascript">
  // Using Regular expression
  function toCommas(value) {
    return value.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
  }

  function commas() {
    var num1 = document.myform.number1.value;

    // Using Regular expression
    document.getElementById('result1').value = toCommas(parseInt(num1));
    // Using toLocaleString()

    document.getElementById('result2').value = parseInt(num1).toLocaleString('ja-JP', {
      style: 'currency',
      currency: 'JPY'
    });

    // Using Intl.NumberFormat()
    document.getElementById('result3').value = new Intl.NumberFormat('ja-JP', {
      style: 'currency',
      currency: 'JPY'
    }).format(num1);
  }
</script>
<FORM NAME="myform">
  <INPUT TYPE="text" NAME="number1" VALUE="123456789">
  <br>
  <INPUT TYPE="button" NAME="button" Value="=>" onClick="commas()">
  <br>Using Regular expression
  <br>
  <INPUT TYPE="text" ID="result1" NAME="result1" VALUE="">
  <br>Using toLocaleString()
  <br>
  <INPUT TYPE="text" ID="result2" NAME="result2" VALUE="">
  <br>Using Intl.NumberFormat()
  <br>
  <INPUT TYPE="text" ID="result3" NAME="result3" VALUE="">

</FORM>

Verim

Verim http://jsben.ch/sifRd


Dinamik olarak yazıyorsanız bu çalışmaz. Eğer ona sadece bir değer verirseniz, ama sürekli olarak dinamik olarak bir değer besliyorsanız, virgüller yanlış yere eklenir.
Edgar Quintero

Cevabımın altındaki demoyu güncelledim. Metin kutusuna dinamik bir değer girerken. Denemek @EdgarQuintero
Tính Ngô Quang

39

Intl.NumberFormat

Yerel JS işlevi. IE11, Edge, en son Safari, Chrome, Firefox, Opera, iOS'ta Safari ve Android'de Chrome tarafından desteklenmektedir.

var number = 3500;

console.log(new Intl.NumberFormat().format(number));
// → '3,500' if in US English locale

Cevabınız yorumlarınıza yanıt olarak güncellendi. Teşekkürler!
Dustin Sun

35

Yanıtları için herkese teşekkürler. Daha "tek bedene uygun" bir çözüm yapmak için bazı cevaplardan yola çıktım.

İlk pasajı taklit olduğu bir işlev ekler PHP 's number_format()Numara prototip. Bir sayıyı biçimlendiriyorsam, işlevin gösterilecek ondalık basamak sayısını alması için genellikle ondalık basamaklar istiyorum. Bazı ülkeler ondalık sayı olarak virgül ve binlik ayırıcı olarak ondalık sayı kullanır, böylece işlev bu ayırıcıların ayarlanmasına izin verir.

Number.prototype.numberFormat = function(decimals, dec_point, thousands_sep) {
    dec_point = typeof dec_point !== 'undefined' ? dec_point : '.';
    thousands_sep = typeof thousands_sep !== 'undefined' ? thousands_sep : ',';

    var parts = this.toFixed(decimals).split('.');
    parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, thousands_sep);

    return parts.join(dec_point);
}

Bunu aşağıdaki gibi kullanırsınız:

var foo = 5000;
console.log(foo.numberFormat(2)); // us format: 5,000.00
console.log(foo.numberFormat(2, ',', '.')); // european format: 5.000,00

Sıklıkla matematik işlemleri için sayıyı geri almam gerektiğini buldum, ancak parseFloat 5.000'i 5'e dönüştürüyor, sadece tamsayı değerlerinin ilk sırasını alıyor. Bu yüzden kendi şamandıra dönüştürme işlevimi oluşturdum ve String prototipine ekledim.

String.prototype.getFloat = function(dec_point, thousands_sep) {
    dec_point = typeof dec_point !== 'undefined' ? dec_point : '.';
    thousands_sep = typeof thousands_sep !== 'undefined' ? thousands_sep : ',';

    var parts = this.split(dec_point);
    var re = new RegExp("[" + thousands_sep + "]");
    parts[0] = parts[0].replace(re, '');

    return parseFloat(parts.join(dec_point));
}

Şimdi her iki işlevi de aşağıdaki gibi kullanabilirsiniz:

var foo = 5000;
var fooString = foo.numberFormat(2); // The string 5,000.00
var fooFloat = fooString.getFloat(); // The number 5000;

console.log((fooString.getFloat() + 1).numberFormat(2)); // The string 5,001.00

2
Çok güzel, ilk yöntemi ödünç aldım;) Ama bir Avrupa formatı kullanmak istediğinizde doğru bir sonuç vermez ve sayı kesirli. Satır 5 şöyle olmalıdır:var parts = this.toFixed(decimals).toString().split('.');
vbwx

Haklısın! toFixed (), virgül bir noktaya değiştirir ve böylece '.' yerine kullanılmalıdır var dec_point. Bunu işaret ettiğiniz için teşekkürler.
Hiçbiri

bunun için bir npm modülü yapabilir misiniz?
chovy

3
@ J.Money .toString gereksizdir, toFixed zaten bir dize döndürür.
Ariel

Neden burada PHP'den bahsettiğinizi bilmiyorum ya da zaten var
vsync

27

Bu sorunun cevabından çok etkilendim. Ukolka'nın cevabını beğendim :

n.toLocaleString()

Ancak ne yazık ki, İspanyolca gibi bazı yerlerde, 10.000'in altındaki sayılar için beklendiği gibi (IMHO) çalışmıyor:

Number(1000).toLocaleString('ES-es')

Verir 1000ve vermez 1.000.

Bkz toLocaleString tüm tarayıcılarda az 10000 den sayılar çalışmıyor neden bilmek.

Bu yüzden Elias Zamaria tarafından doğru binlerce ayırıcı karakteri seçerek cevap kullanmak zorunda kaldım :

n.toString().replace(/\B(?=(\d{3})+(?!\d))/g, Number(10000).toLocaleString().substring(2, 3))

Bu, her iki yerel ayar için tek astar olarak ,veya .binlerce ayırıcı olarak iyi çalışır ve her durumda 1.000'den çalışmaya başlar.

Number(1000).toString().replace(/\B(?=(\d{3})+(?!\d))/g, Number(10000).toLocaleString().substring(2, 3))

1.000İspanyolca yerel ayarlarıyla verir .

Bir sayının biçimlendirilme şekli üzerinde mutlak denetime sahip olmak istiyorsanız, aşağıdakileri de deneyebilirsiniz:

let number   = 1234.567
let decimals = 2
let decpoint = '.' // Or Number(0.1).toLocaleString().substring(1, 2)
let thousand = ',' // Or Number(10000).toLocaleString().substring(2, 3)

let n = Math.abs(number).toFixed(decimals).split('.')
n[0] = n[0].split('').reverse().map((c, i, a) =>
  i > 0 && i < a.length && i % 3 == 0 ? c + thousand : c
).reverse().join('')
let final = (Math.sign(number) < 0 ? '-' : '') + n.join(decpoint)

console.log(final)

Verir 1,234.57.

Bunun düzenli bir ifadeye ihtiyacı yoktur. İlk önce sayıyı istenen ondalık sayıya ayarlayarak toFixed, sonra ondalık noktaya bölerek çalışır .. Sol taraf daha sonra ters çevrilmiş bir basamak dizisine dönüştürülür. Daha sonra her üç basamağa en baştan bin bir ayırıcı eklenir ve sonuç tekrar tersine çevrilir. Nihai sonuç, iki bölümün birleşmesidir. Önce giriş numarasının işareti kaldırılır Math.absve sonra gerekirse geri konur.

Tek astar değil, çok daha uzun ve kolayca bir işleve dönüşüyor. Netlik sağlamak için değişkenler eklenmiştir, ancak önceden biliniyorsa bunlar istenen değerlerle değiştirilebilir. toLocaleStringOndalık nokta için doğru karakterleri ve geçerli yerel ayar için binlerce ayırıcıyı bulmak için kullanılan ifadeleri kullanabilirsiniz (bunların daha modern bir Javascript gerektirdiğini unutmayın.)


23

Bence bu bunu yapan en kısa düzenli ifade:

/\B(?=(\d{3})+\b)/g

"123456".replace(/\B(?=(\d{3})+\b)/g, ",")

Birkaç sayı üzerinde kontrol ettim ve işe yaradı.


Bu durumda bir ayırıcıdan sonra 3'ten fazla sayı ile kayan sayı yoksa sadece iyi çalışır. Aksi takdirde virgül de ekler. "1234567890.1234567890" .replace (/ \ B (? = (\ D {3}) + \ b) / g, ",") Bu, örneğin işe yaramaz. "1,234,567,890,1,234,567,890" değerini döndürür
Marcio

1
Para için olsa iyi çalışıyor! Virgül eklemeden önce rakamlarınızı yuvarlamanız yeterlidir.
Kyle Chadha

1
Ondalık noktadan sonra ekler: 12.3456 ".replace (/ \ B (? = (\ D {3}) + \ b) / g,", ") == 12.3,456
Shree Tiwari

21

Number.prototype.toLocaleString()doğal olarak tüm tarayıcılar (Safari) tarafından sağlanan olsaydı harika olurdu .

Diğer tüm cevapları kontrol ettim ama kimse çoklu dolduruyor gibiydi. İşte aslında ilk iki cevabın bir kombinasyonu olan bir poc; çalışırsa toLocaleStringkullanırsa, özel bir işlev kullanır.

var putThousandsSeparators;

putThousandsSeparators = function(value, sep) {
  if (sep == null) {
    sep = ',';
  }
  // check if it needs formatting
  if (value.toString() === value.toLocaleString()) {
    // split decimals
    var parts = value.toString().split('.')
    // format whole numbers
    parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, sep);
    // put them back together
    value = parts[1] ? parts.join('.') : parts[0];
  } else {
    value = value.toLocaleString();
  }
  return value;
};

alert(putThousandsSeparators(1234567.890));


1
Çoklu dolgunun yalnızca en fazla 3 ondalık sayıya sahip sayılarla çalıştığını unutmayın. Örneğin: 0.12345çıktı alacaktır 0.12,345. Bunun için iyi bir uygulama alt
Andy

haklısın, value > 1000eğer if durumuna bu durumu düzeltir, ancak bu bir poc idi ve elbette daha iyi test edilmiş versiyonlar başka bir yerde bulunabilir, işaret ettiğiniz için teşekkürler.
Sinan

1
Koymak yeterli değildir value > 1000, çünkü herhangi bir sayı ve 3 ondalık basamak için aynı olacaktır. örneğin 1000.12345geri döner 1,000.12,345. Cevabınız harika ve doğru yolda, ama tam değil. Ben sadece cevabınız üzerinde yanılmak ve sadece farklı giriş verileri ile test etmeden kopyalamak / makarna olabilir diğer insanlar için işaret etmeye çalışıyordu.
Andy

1
tamam, bu başka bir düzenleme gerekli :) Kabul ediyorum, ama şimdi en azından çoğu durumda çalışması gerekir.
Sinan

18

Binlik ayırıcı, tarayıcının Intlnesnesi kullanılarak uluslararası dostu bir şekilde eklenebilir :

Intl.NumberFormat().format(1234);
// returns "1,234" if the user's locale is en_US, for example

Daha fazla bilgi için MDN'nin NumberFormat ile ilgili makalesine bakın , kullanıcının yerel ayarını veya varsayılanını belirleyebilirsiniz. Bu biraz daha kusursuzdur çünkü yerel farklılıklara saygı duyar; birçok ülke rakamları ayırmak için nokta kullanırken virgül ondalık sayıları belirtir.

Intl.NumberFormat henüz tüm tarayıcılarda mevcut değildir, ancak en son Chrome, Opera ve IE'de çalışır. Firefox'un bir sonraki sürümü bunu desteklemelidir. Webkit'in uygulama için bir zaman çizelgesi yok gibi görünüyor.


2
Basit bir yerleşik işlev kullanabilseydik bu harika olurdu, ancak korkunç bir tarayıcı uygulaması var. Örneğin, IE 8-10 ve tüm Safari bunu desteklemez
Blaine Kasten

@BlaineKasten burada eski tarayıcılar için tam uyumlu bir çoklu dolgu var: github.com/andyearnshaw/Intl.js çok büyük, ama çalışıyor.
Mahn

1
Pollyfill CDN aracılığıyla kullanılabilir (yalnızca kullanıcılara göre gerekli olanı döndürür): cdn.polyfill.io/v2/polyfill.min.js?features=Intl
Kevin

ToLocaleString ile büyük sayıları biçimlendirme sorunları vardı, bu harika çalıştı (
çoklu dolgu

18

Para birimi gereksiniminizi biçimlendirmek için bu yordamı kullanabilirsiniz.

var nf = new Intl.NumberFormat('en-US', {
  style: 'currency',
  currency: 'USD',
  minimumFractionDigits: 2,
  maximumFractionDigits: 2
});
nf.format(123456.789); // ‘$123,456.79’

Daha fazla bilgi için bu bağlantıya erişebilirsiniz.

https://www.justinmccandless.com/post/formatting-currency-in-javascript/


Bu doğru, taşınabilir, doğal cevaptır. Keşke birden fazla kez oy verebilseydim.
Jared Smith

14

para birimi değerleri ile uğraşıyorsanız ve çok biçimlendiriyorsanız, çok sayıda büyük durumu ve yerelleştirmeyi işleyen küçük muhasebe.js eklemeye değer olabilir :

// Default usage:
accounting.formatMoney(12345678); // $12,345,678.00

// European formatting (custom symbol and separators), could also use options object as second param:
accounting.formatMoney(4999.99, "€", 2, ".", ","); // €4.999,99

// Negative values are formatted nicely, too:
accounting.formatMoney(-500000, "£ ", 0); // £ -500,000

// Simple `format` string allows control of symbol position [%v = value, %s = symbol]:
accounting.formatMoney(5318008, { symbol: "GBP",  format: "%v %s" }); // 5,318,008.00 GBP

1
Bağlantı artık çalışmıyor. Ama buna benzer: openexchangerates.github.io/accounting.js
ush189

13

Aşağıdaki kod karakter taramasını kullanır, bu nedenle normal ifade yoktur.

function commafy( num){
  var parts = (''+(num<0?-num:num)).split("."), s=parts[0], L, i=L= s.length, o='';
  while(i--){ o = (i===0?'':((L-i)%3?'':',')) 
                  +s.charAt(i) +o }
  return (num<0?'-':'') + o + (parts[1] ? '.' + parts[1] : ''); 
}

Gelecek vaat eden performansı gösterir: http://jsperf.com/number-formatting-with-commas/5

2015.4.26: Num <0 olduğunda sorunu çözmek için küçük düzeltme. Bkz. Https://jsfiddle.net/runsun/p5tqqvs3/


ile yapar değil iş commafy(-123456)o verir-,123,456
wrossmck

Bu harika! JSperf'i bir araya getirdiğiniz için teşekkürler
fregante

Bu parçacık mutlak bir canavardır, her şeyi yerine getirir.
NiCk Newman

13

İşte bin ayırıcı için virgül ekleyen basit bir işlev. RegEx yerine dizi işlevlerini kullanır.

/**
 * Format a number as a string with commas separating the thousands.
 * @param num - The number to be formatted (e.g. 10000)
 * @return A string representing the formatted number (e.g. "10,000")
 */
var formatNumber = function(num) {
    var array = num.toString().split('');
    var index = -3;
    while (array.length + index > 0) {
        array.splice(index, 0, ',');
        // Decrement by 4 since we just added another unit to the array.
        index -= 4;
    }
    return array.join('');
};

Örneklerle CodeSandbox bağlantısı: https://codesandbox.io/s/p38k63w0vq


1
Merhaba .. Bu örnek harika. Ancak ondalık kısım için virgül koyacaktır. sadece bir düzenleme: işlev formatNumber (num) {var decimalPart = ''; num = num.toString (); if (num.indexOf ('.')! = -1) {decimalPart = '.' + num.split ('.') [1]; num = parseInt (num.split ('.') [0]); } var dizi = num.toString (). bölünmüş (''); var indeksi = -3; while (dizi.length + dizin> 0) {dizi.splice (dizin, 0, ','); // Diziye yeni bir birim daha eklediğimizden beri 4 azaltıldı. indeks - = 4; } dönüş array.join ('') + decimalPart; };
Aki143S

Teşekkürler bayım. Tam da ihtiyacım olan şey bu.
Amir Hossein Ahmadi

11

Hindistan için para birimi biçimini işlemek için bu kodu kullanın. Ülke kodu, diğer ülke para birimlerini işlemek için değiştirilebilir.

let amount =350256.95
var formatter = new Intl.NumberFormat('en-IN', {
  minimumFractionDigits: 2,
});

// Use it.

formatter.format(amount);

çıktı:

3,50,256.95

Bu kod soruyu cevaplayabilirken, sorunun nasıl ve / veya neden çözüldüğüne dair ek bağlam sağlamak yanıtlayıcının uzun vadeli değerini artıracaktır. Bunu okuyun .
Shanteshwar Inde

Kesinlikle cevabı geliştirmek için ek bağlam ekleyeceğim
Bathri Nathan

11

Ayrıca Intl.NumberFormat yapıcısını da kullanabilirsiniz . Bunu nasıl yapabileceğiniz aşağıda açıklanmıştır.

 resultNumber = new Intl.NumberFormat('en-IN', { maximumSignificantDigits: 3 }).format(yourNumber); 

bu çalışmayan düğüm js. Hint formatında cevap
vermiyor

7

Ben bu yazı üzerine tökezlemeden önce yazdım. Normal ifade yok ve kodu gerçekten anlayabilirsiniz.

$(function(){
  
  function insertCommas(s) {

    // get stuff before the dot
    var d = s.indexOf('.');
    var s2 = d === -1 ? s : s.slice(0, d);

    // insert commas every 3 digits from the right
    for (var i = s2.length - 3; i > 0; i -= 3)
      s2 = s2.slice(0, i) + ',' + s2.slice(i);

    // append fractional part
    if (d !== -1)
      s2 += s.slice(d);

    return s2;

  }
  
  
  $('#theDudeAbides').text( insertCommas('1234567.89012' ) );
  
  
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

<div id="theDudeAbides"></div>


1
Ben sadece dizeleri değil, sayıları da kabul böylece fonksiyonun başında s.toString () ekledi. Bu benim tercih ettiğim cevaptır çünkü okunabilir, özlüdür ve normal cevapların sahip olduğu hataları içermez.
FeFiFoFu

7
var formatNumber = function (number) {
  var splitNum;
  number = Math.abs(number);
  number = number.toFixed(2);
  splitNum = number.split('.');
  splitNum[0] = splitNum[0].replace(/\B(?=(\d{3})+(?!\d))/g, ",");
  return splitNum.join(".");
}

EDIT: İşlev yalnızca pozitif sayıyla çalışır. örnek için:

var number = -123123231232;
formatNumber(number)

Çıktı: "123,123,231,232"

Ancak yukarıdaki soruyu cevaplamak için toLocaleString()yöntem sadece sorunu çözer.

var number = 123123231232;
    number.toLocaleString()

Çıktı: "123,123,231,232"

Cheer!


1
Bu kod soruyu cevaplayabilirken, sorunun nasıl ve / veya neden çözüldüğüne dair ek bağlam sağlamak yanıtlayıcının uzun vadeli değerini artıracaktır.
Donald Duck

1
Güzel bir senaryo, ancak negatif sayılarla çalışmıyor.
Ralph David Abernathy

7

Cevabım, jQuery'nin yerine çok daha mantıklı bir alternatif olan tek cevap:

function $(dollarAmount)
{
    const locale = 'en-US';
    const options = { style: 'currency', currency: 'USD' };
    return Intl.NumberFormat(locale, options).format(dollarAmount);
}

Bu çözüm yalnızca virgül $(1000.9999)eklemekle kalmaz , aynı zamanda 1,001,00 $ alacaksınız gibi bir tutar girmeniz durumunda en yakın kuruşa da yuvarlar . Ayrıca, girdiğiniz değer güvenli bir şekilde bir sayı veya dize olabilir; önemli değil.

Parayla uğraşıyorsanız, ancak tutarda önde gelen bir dolar işareti gösterilmesini istemiyorsanız, önceki işlevi kullanan ancak aşağıdakileri kaldıran bu işlevi de ekleyebilirsiniz $:

function no$(dollarAmount)
{
    return $(dollarAmount).replace('$','');
}

Eğer ediyorsanız değil para ile uğraşan ve ondalık biçimlendirme gereksinimleri değişen var, burada daha fonksiyonu çok yönlü:

function addCommas(number, minDecimalPlaces = 0, maxDecimalPlaces = Math.max(3,minDecimalPlaces))
{
    const options = {};
    options.maximumFractionDigits = maxDecimalPlaces;
    options.minimumFractionDigits = minDecimalPlaces;
    return Intl.NumberFormat('en-US',options).format(number);
}

Oh, ve bu arada, bu kodun Internet Explorer'ın bazı eski sürümlerinde çalışmıyor olması tamamen kasıtlı. Modern standartları desteklemeyen yakalayabildiğim zaman IE'yi kırmaya çalışıyorum.

Lütfen, yorum bölümünde aşırı övgünün konu dışı olarak değerlendirildiğini unutmayın. Bunun yerine, sadece oyla duş al.


1
Number (n) .toLocaleString () en iyi yanıt gibi görünüyor, ancak dolar işaretlerini ve ondalık sayıları sıyırmak yerine muhtemelen yeni Intl.NumberFormat ('en-US'). Biçimi (n) gibi bir şey kullanmak istersiniz. kullanıcı istediği sayılarında virgül olur.
bmacnaughton

@bmacnaughton: Parayla uğraşmadığınızda iyi bir nokta. Bununla birlikte, parayla uğraşıyorsanız ve sadece "önde gelen dolar işareti istemiyorsanız", Number (1000.50) .toLocaleString (), '1,000.5' üretir ve bu da para değerlerini görüntülerken genellikle tutulan önemsiz sıfırı kaldırır. Yine de iyi yorum: herkes ne dediğini bilmeli.
Lonnie En İyi

6

Benim için en iyi yanıt, bazı üyelerin söylediği gibi toLocaleString kullanmaktır. '$' Sembolünü eklemek istiyorsanız sadece dil ve yazım seçenekleri ekleyin. Bir sayıyı Meksika Pezosu olarak biçimlendirmek için örnek ve örnek

var n = 1234567.22
alert(n.toLocaleString("es-MX",{style:"currency", currency:"MXN"}))

kısayol

1234567.22.toLocaleString("es-MX",{style:"currency", currency:"MXN"})

5

Beni geliştirmeye çalışalım uKolka 'ın cevabı bir süre tasarrufu belki ve yardım diğerleri.

Numeral.js kullanın .

document.body.textContent = numeral(1234567).format('0,0');
<script src="//cdnjs.cloudflare.com/ajax/libs/numeral.js/1.4.5/numeral.min.js"></script>

Sen ile gitmeli Number.prototype.toLocaleString () onun yalnızca tarayıcı uyumluluk bir sorun değildir.


Bu bana npm yükleme rakamı ilham verdi
steampowered

5

Ondalık basamakları, farklı ayırıcıları ve negatifleri destekleyen alternatif bir yol.

var number_format = function(number, decimal_pos, decimal_sep, thousand_sep) {
    var ts      = ( thousand_sep == null ? ',' : thousand_sep )
        , ds    = ( decimal_sep  == null ? '.' : decimal_sep )
        , dp    = ( decimal_pos  == null ? 2   : decimal_pos )

        , n     = Math.floor(Math.abs(number)).toString()

        , i     = n.length % 3 
        , f     = ((number < 0) ? '-' : '') + n.substr(0, i)
    ;

    for(;i<n.length;i+=3) {
        if(i!=0) f+=ts;
        f+=n.substr(i,3);
    }

    if(dp > 0) 
        f += ds + parseFloat(number).toFixed(dp).split('.')[1]

    return f;
}

@Jignesh Sanghani tarafından yapılan bazı düzeltmeler, yorumunu yükseltmeyi unutmayın.


Benim için mükemmel, işlemeden önce biçimlendirmeyi kaldırmak için yeni bir satır ekledim.
Dennis Heiden

2
fn.substr(0, i)ile değiştirin n.substr(0, i)ve number.toFixed(dp).split('.')[1]ile değiştirin parseFloat(number).toFixed(dp).split('.')[1]. çünkü doğrudan kullandığımda hata veriyor. lütfen kodunuzu güncelleyin
Jignesh Sanghani

kusurlu. sayısı artar. bir örnek çağrı harika olurdu!
20mm19

tavanı zemine geçirmek bunu düzeltti, ancak başka hangi sorunların ortaya çıkacağından emin değildi.
20mm19

1
Math.floor (-75.1);)
mmm

4

Bu işlevin bu sorunla ilgili tüm sorunları halledeceğini düşünüyorum.

function commaFormat(inputString) {
    inputString = inputString.toString();
    var decimalPart = "";
    if (inputString.indexOf('.') != -1) {
        //alert("decimal number");
        inputString = inputString.split(".");
        decimalPart = "." + inputString[1];
        inputString = inputString[0];
        //alert(inputString);
        //alert(decimalPart);

    }
    var outputString = "";
    var count = 0;
    for (var i = inputString.length - 1; i >= 0 && inputString.charAt(i) != '-'; i--) {
        //alert("inside for" + inputString.charAt(i) + "and count=" + count + " and outputString=" + outputString);
        if (count == 3) {
            outputString += ",";
            count = 0;
        }
        outputString += inputString.charAt(i);
        count++;
    }
    if (inputString.charAt(0) == '-') {
        outputString += "-";
    }
    //alert(outputString);
    //alert(outputString.split("").reverse().join(""));
    return outputString.split("").reverse().join("") + decimalPart;
}

4

Sadece gelecekteki Google çalışanları için (veya ille de 'Google çalışanları' değil):

Yukarıda belirtilen tüm çözümler harika, ancak RegExp böyle bir durumda kullanmak çok kötü bir şey olabilir.

Yani, evet, önerilen seçeneklerden bazılarını kullanabilir veya hatta ilkel ancak kullanışlı bir şey yazabilirsiniz:

const strToNum = str => {

   //Find 1-3 digits followed by exactly 3 digits & a comma or end of string
   let regx = /(\d{1,3})(\d{3}(?:,|$))/;
   let currStr;

   do {
       currStr = (currStr || str.split(`.`)[0])
           .replace( regx, `$1,$2`)
   } while (currStr.match(regx)) //Stop when there's no match & null's returned

   return ( str.split(`.`)[1] ) ?
           currStr.concat(`.`, str.split(`.`)[1]) :
           currStr;

};

strToNum(`123`) // => 123
strToNum(`123456`) // => 123,456
strToNum(`-1234567.0987`) // => -1,234,567.0987

Burada kullanılan normal ifade oldukça basittir ve döngü işin tamamlanması için tam olarak kaç kez geçeceğini belirtir.

Ve daha iyi optimize edebilirsiniz, "DRYify" kodu vb.

Hala,

(-1234567.0987).toLocaleString();

(çoğu durumda) çok daha iyi bir seçim olacaktır.

Bu nokta, yürütme hızında veya tarayıcılar arası uyumlulukta değil.

Ortaya çıkan sayıyı kullanıcıya göstermek istediğiniz durumlarda, .toLocaleString () yöntemi, web sitenizin veya uygulamanızın kullanıcısıyla (dili ne olursa olsun) aynı dili konuşmanız için süper güç verir.

ECMAScript belgelerine göre bu yöntem 1999 yılında tanıtıldı ve bunun bir noktada internetin tüm dünyadaki insanları birbirine bağlayacağı umuduydu, bu yüzden bazı "içselleştirme" araçlarına ihtiyaç duyuldu.

Bugün İnternet hepimizi birbirine bağlıyor, bu yüzden dünyanın hayal edebileceğimizden çok daha karmaşık olduğunu ve (/ neredeyse) hepimizin burada , İnternet'te olduğunu hatırlamak önemlidir .

Açıkçası, insanların çeşitliliği göz önüne alındığında, herkes için mükemmel UX garanti etmek imkansız çünkü farklı diller konuşuyoruz, farklı şeylere değer veriyoruz, vb. Ve tam olarak bu nedenle, şeyleri mümkün olduğunca yerelleştirmeye çalışmak daha da önemlidir. .

Dolayısıyla, tarih, saat, sayılar, vb. Temsili için bazı özel standartlar olduğu ve bu şeyleri son kullanıcı tarafından tercih edilen formatta görüntülemek için bir aracımız olduğu düşünüldüğünde, bu nadir değildir ve neredeyse sorumsuz değildir. bu aracı kullanın (özellikle bu verileri kullanıcıya görüntülemek istediğimiz durumlarda)?

Benim için, böyle bir durumda .toLocaleString () yerine RegExp kullanmak, JavaScript ile bir saat uygulaması oluşturmak ve bunu böyle bir şekilde kodlamak gibi görünüyor, bu yüzden sadece Prag saatini görüntüleyecek ( Prag'da yaşamayan insanlar)

new Date();

verileri son kullanıcının saatine göre döndürmektir.


işlevi const ve => ile neden yazdınız?
OG Sean

@OGSean Değişkenleri ve işlevleri bildirmenin en uygun yolu olduğu için her zaman yaparım. Ayrıca, kodu daha temiz ve daha kısa tutmaya yardımcı olduğunu düşünüyorum.
Igor Bykov

4

Benim gerçek normal-ifadeler-tek çözüm bu aşk tek gömlekleri için

Yukarıdaki hevesli oyuncuları görüyor musunuz? Belki de golf oynayabilirsiniz. İşte vuruşum.

n => `${n}`.replace(/(?<!\.\d+)\B(?=(\d{3})+\b)/g, " ").replace(/(?<=\.(\d{3})+)\B/g, " ")

Uluslararası Birimler Sisteminin SI Broşür: Uluslararası Birimler Sistemi (SI)yayınının sekizinci baskısında (2006) yaptığı gibi, binlerce ayırıcı için bir İNCE ALAN (U + 2009) kullanır (Bkz. §5.3 .4.). Dokuzuncu baskı (2019) bunun için bir alan kullanılmasını önermektedir (Bakınız §5.4.4.). Virgül dahil istediğiniz her şeyi kullanabilirsiniz.


Görmek.

const integer_part_only = n => `${n}`.replace(/(?<!\.\d+)\B(?=(\d{3})+\b)/g, " I ");
const fractional_part_only = n => `${n}`.replace(/(?<=\.(\d{3})+)\B/g, " F ");
const both = n => fractional_part_only(integer_part_only(n));

function demo(number) { // I’m using Chrome 74.
	console.log(`${number}
		 "${integer_part_only(number)}" (integer part only)
		 "${fractional_part_only(number)}" (fractional part only)
		 "${both(number)}" (both)
	`);
}
demo(Math.random() * 10e5);
demo(123456789.01234567);
demo(123456789);
demo(0.0123456789);


O nasıl çalışır?

Tam sayı için

.replace(/(?<!\.\d+)\B(?=(\d{3})+\b)/g, " I ")
  • .replace(……, " I ") “Ben” koy
    • /……/g her birinde
      • \B bitişik iki basamağın arasında
        • (?=……)Sağ kısmı olan POZİTİF LOOKAHEAD
          • (\d{3})+ bir veya daha fazla üç haneli parçalar
          • \b ardından nokta, dizenin sonu, et cetera,
        • (?<!……)NEGATİF LOOKBEHIND , sol kısmı olanlar hariç
          • \.\d+ noktadan sonra basamak gelir (“ondalık ayırıcısı vardır”).

Ondalık kısım için

.replace(/(?<=\.(\d{3})+)\B/g, " F ")
  • .replace(……, " F ") “F” koy
    • /……/g her birinde
      • \B bitişik iki basamağın arasında
        • (?<=……)Sol kısmı olan POZİTİF GÖRÜN
          • \. ondalık ayırıcı
          • (\d{3})+ ardından bir veya daha fazla üç haneli parçalar.

Karakter sınıfları ve sınırları

\d

Herhangi bir rakamla eşleşir (Arapça rakamı). İle eşdeğerdir [0-9].

Örneğin,

  • /\d/ya /[0-9]/maçları 2içinde B2 is the suite number.

\b

Bir kelime sınırıyla eşleşir . Bu, bir kelime karakterinin, harf ve boşluk gibi başka bir kelime karakteri tarafından takip edilmediği veya öncesinde olmadığı konumdur. Eşleşen kelime sınırının eşleşmeye dahil edilmediğini unutmayın. Başka bir deyişle, eşleşen bir sözcük sınırının uzunluğu sıfırdır.

Örnekler:

  • /\bm/maçları miçinde moon;
  • /oo\b/eşleşmiyor ooin moon, çünkü ootakip eder nbir kelime karakteri olan;
  • /oon\b/maçları oonin moon, çünkü oonböylece bir sözcük karakteri tarafından takip değil dize sonu olduğu;
  • /\w\b\w/ hiçbir şeyle eşleşmeyecektir, çünkü bir kelime karakterini hem kelime olmayan hem de kelime karakteri izleyemez.

\B

Sözcük olmayan bir sınırla eşleşir . Bu, önceki ve sonraki karakterin aynı türde olduğu bir konumdur: her ikisi de kelime olmalı ya da her ikisi de kelime olmayan olmalıdır. İki harf arasında veya iki boşluk arasında. Bir dizenin başlangıcı ve sonu sözcük olmayan olarak kabul edilir. Eşleşen kelime sınırı ile aynı, eşlenen kelime olmayan sınır da maça dahil değildir.

Örneğin,

  • /\Bon/maçları oniçinde at noon;
  • /ye\B/maçları yeiçinde possibly yesterday.

Tarayıcı Uyumluluğu


3

Aki143S'nin çözümüne düzeltildi ekledim . Bu çözüm, binlerce ayırıcı için noktalar ve hassasiyet için virgül kullanır.

function formatNumber( num, fixed ) { 
    var decimalPart;

    var array = Math.floor(num).toString().split('');
    var index = -3; 
    while ( array.length + index > 0 ) { 
        array.splice( index, 0, '.' );              
        index -= 4;
    }

    if(fixed > 0){
        decimalPart = num.toFixed(fixed).split(".")[1];
        return array.join('') + "," + decimalPart; 
    }
    return array.join(''); 
};

Örnekler;

formatNumber(17347, 0)  = 17.347
formatNumber(17347, 3)  = 17.347,000
formatNumber(1234563.4545, 3)  = 1.234.563,454

3

Zaten çok iyi cevaplar. İşte sadece eğlence için bir başkası:

function format(num, fix) {
    var p = num.toFixed(fix).split(".");
    return p[0].split("").reduceRight(function(acc, num, i, orig) {
        if ("-" === num && 0 === i) {
            return num + acc;
        }
        var pos = orig.length - i - 1
        return  num + (pos && !(pos % 3) ? "," : "") + acc;
    }, "") + (p[1] ? "." + p[1] : "");
}

Bazı örnekler:

format(77.03453, 2); // "77.03"
format(78436589374); // "78,436,589,374"
format(784, 4);      // "784.0000"
format(-123456);     // "-123,456"

ile yapar değil iş format(-123456)o verir-,123,456
wrossmck

1
(Her seferinde işareti kontrol etmeden yapmanın muhtemelen daha zarif bir yolu olmasına rağmen) düzeltildi. Her durumda, güncelleştirme bu işlemi negatif sayılarla çalıştırır.
Wayne
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.