Javascript Thousand Separator / รูปแบบสตริง [ซ้ำ]


105

มีฟังก์ชันใด ๆ ใน Javascript สำหรับการจัดรูปแบบตัวเลขและสตริงหรือไม่?

ฉันกำลังมองหาวิธีพันตัวคั่นสำหรับสตริงหรือตัวเลข ... (ชอบ String รูปแบบใน c #)



ฉันคิดว่าคุณจะพบสิ่งที่คุณต้องการในนั้น :) stackoverflow.com/questions/610406/…
Jad

How to print a number with commas as thousands separators in JavaScript: stackoverflow.com/questions/2901102/…
Adrien Be

คำตอบ:


184

อัปเดต (7 ปีต่อมา)

การอ้างอิงที่อ้างถึงในคำตอบเดิมด้านล่างนี้ผิด มีถูกสร้างขึ้นในฟังก์ชั่นนี้ซึ่งเป็นสิ่งที่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)


คำตอบเดิม

ตามข้อมูลอ้างอิงนี้ไม่มีฟังก์ชันในตัวสำหรับการเพิ่มลูกน้ำลงในตัวเลข แต่หน้านั้นมีตัวอย่างวิธีการเขียนโค้ดด้วยตัวคุณเอง:

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

ทำงานร่วมกับ javascript บริสุทธิ์ + regex เดียวแทนที่ stackoverflow.com/a/44324879/681830
Val

4
ใช้(1234567).toLocaleString().replace(/,/g," ",)สำหรับช่องว่างระหว่างหลายพัน
Fanky

125

หากเกี่ยวกับการแปลตัวคั่นหลายพันตัวคั่นและตัวคั่นทศนิยมให้ดำเนินการดังต่อไปนี้:

// --> 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

แก้ไข: commentor @I เช่นเซเรน่าจะเพิ่มต่อไปนี้:

เพื่อสนับสนุนเบราว์เซอร์ที่มีสถานที่ที่ไม่ใช่ภาษาอังกฤษที่เรายังคงต้องการการจัดรูปแบบภาษาอังกฤษ, value.toLocaleString('en')การใช้งาน ยังใช้สำหรับจุดลอย


สิ่งนี้ไม่ครอบคลุมตัวเลขทศนิยม .. คุณสามารถเปลี่ยน parseInt เป็น parseFloat ได้ แต่ถ้า yourInt = "100,12" (ลูกน้ำเป็นตัวคั่นทศนิยม) สิ่งนี้จะล้มเหลว ซึ่งสามารถแก้ไขได้ด้วยการแทนที่ (",", ".") .. แต่จะล้มเหลวอีกครั้งด้วย "1.000,12" ดังนั้น ... คุณต้องสร้างล้อใหม่ในบางครั้ง stackoverflow.com/a/2901298/1028304
neiker

1
สิ่งนี้จะเหมาะสมกว่า:Number(yourNumberOrString).toLocaleString()
Jonathan

2
เพื่อสนับสนุนเบราว์เซอร์ที่มีสถานที่ที่ไม่ใช่ภาษาอังกฤษที่เรายังคงต้องการการจัดรูปแบบภาษาอังกฤษ, value.toLocaleString('en')การใช้งาน ยังใช้สำหรับจุดลอย
Klaas van Aarsen

1
@ Serhiog.Lazin อะไรที่ไม่ทำงานบน Safari (และระบบปฏิบัติการใดและเวอร์ชันใด)
kaiser

2
FYI สำหรับรูปแบบตัวเลขของอินเดียเช่น7,77,77,777ใช้value.toLocaleString('en-IN')
ทำให้

39

อัปเดตโดยใช้การสนับสนุน Look-behind ซึ่งสอดคล้องกับการเปลี่ยนแปลง 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))

»คำอธิบาย Verbose regex (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))

»คำอธิบาย Verbose regex (regex101.com)

แผนภาพการไหล


แผนภาพไวยากรณ์นี้ถูกสร้างบน regex101.com หรือไม่
Gerold Broser

เกิดอะไรขึ้นกับตัวเลขที่มีทศนิยม?
Emiliano

ฉันได้รับ "นิพจน์ทั่วไปไม่ถูกต้อง: ชื่อตัวระบุกลุ่มไม่ถูกต้อง" ใน React Native 0.59 ทำสิ่งนี้ แต่ไม่ควรส่งผลกระทบต่อ RegEx
Joshua Pinter

@JoshuaPinter มันจะเป็นการใช้ look-behind ซึ่งในขณะที่เขียนยังไม่รองรับในทุกแพลตฟอร์ม ฉันเดาว่าคุณหมายถึง iOS โดยเฉพาะเนื่องจาก Safari ก็ยังล้มเหลวสำหรับฉันเช่นกัน อาจเป็นการดีที่สุดที่จะใช้เวอร์ชันที่เข้ากันได้แบบย้อนหลังในตอนนี้ ฉันแค่พยายามพิสูจน์คำตอบของฉันในอนาคต caniuse.com/#search=lookbehind
Emissary

1
@Emissary ขอบคุณสำหรับเคล็ดลับ ใช่มันอยู่ใน React Native 0.59 / Android ซึ่งใช้ JavaScriptCore (JSC) เวอร์ชันที่ค่อนข้างเก่ากว่า ฉันจะลองอีกครั้งหลังจากที่เราอัปเดตเป็น React Native 0.60+ ซึ่งรวมถึงการอัปเดต JSC
Joshua Pinter

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);

ทางออกที่ดีที่สุด imho
Michal

ฉันไม่คิดอย่างนั้นการเพิ่มความต้องการไฟล์ใหม่ที่มีเกือบ 800 บรรทัดมันเหมือนกับการฆ่ามดด้วยแกรเนด
Emiliano

6

ฉันใช้สิ่งนี้:

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

ที่มา: ลิงค์


'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;
}   

5
var number = 35002343;

console.log(number.toLocaleString());

สำหรับข้อมูลอ้างอิงคุณสามารถตรวจสอบได้ที่นี่ https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toLocaleString


1
ฮ่า ๆ ๆ ลองใช้ var n = 4720 console.log (n.toLocaleString ()) มันจะไม่ทำงาน
Emiliano


3

คุณสามารถใช้จาวาสคริปต์ ด้านล่างนี้เป็นรหัสซึ่งจะเป็นacceptตัวเลขและหนึ่งเท่านั้นdot

นี่คือจาวาสคริปต์

<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)" />

DEMO JSFIDDLE


2

สิ่งที่คุณต้องทำมีเพียงแค่นี้ :

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

น่าเสียดายที่ขึ้นอยู่กับแพลตฟอร์มของคุณ บางตัวมีtoLocaleString()ที่ไม่เพิ่มเครื่องหมายจุลภาคหรือไม่มีคุณสมบัติอื่น ๆ ในมาตรฐาน ตรวจสอบการtoLocaleStringมีอยู่ได้ง่ายแต่ไม่ต้องตรวจสอบการปฏิบัติตามข้อกำหนด
hippietrail

ลองใช้ตัวเลขระหว่าง 1,000 ถึง 9999
เอมิเลียโน

2
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
คุณช่วยเพิ่มคำอธิบายด้วยเพื่อให้ op และคนอื่น ๆ เข้าใจว่าโค้ดนี้แก้ปัญหาได้อย่างไร ขอบคุณ
Punit Gajjar

ลองกับผู้เสนอชื่อ beteen 1,000 และ 9999
Emiliano

0

การรวมกันของโซลูชันสำหรับปฏิกิริยา

  let converter = Intl.NumberFormat();
  let salary =  monthlySalary.replace(/,/g,'')
  console.log(converter.format(salary))

  this.setState({
    monthlySalary: converter.format(salary)
  })
}

handleOnChangeMonthlySalary(1000)```

0

คุณสามารถใช้ ngx-format-field เป็นคำสั่งในการจัดรูปแบบค่าอินพุตซึ่งจะปรากฏในมุมมอง จะไม่จัดการกับค่าอินพุตซึ่งจะถูกบันทึกไว้ในแบ็กเอนด์ ดูลิงค์ที่นี่ !

ตัวอย่าง:

component.html:

<input type="text" formControlName="currency" [appFormatFields]="CURRENCY"
(change)="onChangeCurrency()">

component.ts

onChangeCurrency() {
this.currency.patchValue(this.currency.value);
}

ดูการสาธิตได้ที่นี่ !


0

คุณสามารถใช้ฟังก์ชันต่อไปนี้:

function format(number, decimals = 2, decimalSeparator = '.', thousandsSeparator = ',') {
  const roundedNumber = number.toFixed(decimals);
  let integerPart = '',
    fractionalPart = '';
  if (decimals == 0) {
    integerPart = roundedNumber;
    decimalSeparator = '';
  } else {
    let numberParts = roundedNumber.split('.');
    integerPart = numberParts[0];
    fractionalPart = numberParts[1];
  }
  integerPart = integerPart.replace(/(\d)(?=(\d{3})+(?!\d))/g, `$1${thousandsSeparator}`);
  return `${integerPart}${decimalSeparator}${fractionalPart}`;
}

// Use Example

let min = 1556454.0001;
let max = 15556982.9999;

console.time('number format');
for (let i = 0; i < 15; i++) {
  let randomNumber = Math.random() * (max - min) + min;
  let formated = format(randomNumber, 4, ',', '.'); // formated number

  console.log('number: ', randomNumber, '; formated: ', formated);
}
console.timeEnd('number format');


อย่าทำให้มันสับสน เพียงแค่ใช้ toLocaleString () ข้อมูลเพิ่มเติมในdeveloper.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Sajad Saderi

@sajadsaderi ฉันยังใช้ toLocaleString () เพื่อน แต่ฟังก์ชันนี้ไม่ได้ให้ความยืดหยุ่นมากนักดังนั้นฉันจึงไม่ต้องจัดการกับตัวย่อภูมิภาคและมีคนอื่นสามารถใช้งานได้เนื่องจากคำจำกัดความของฟังก์ชันนี้เหมือนกับ number_format () ฟังก์ชันของ php.
jin_maxtor

-1

ฉันไม่ชอบคำตอบใด ๆ ที่นี่ดังนั้นฉันจึงสร้างฟังก์ชันที่เหมาะกับฉัน แค่อยากแชร์เผื่อว่าใครเห็นว่ามีประโยชน์

function getFormattedCurrency(num) {
    num = num.toFixed(2)
    var cents = (num - Math.floor(num)).toFixed(2);
    return Math.floor(num).toLocaleString() + '.' + cents.split('.')[1];
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.