Formato stringa / separatore Javascript mille [duplicato]


96

Esiste una funzione in Javascript per la formattazione di numeri e stringhe?

Sto cercando un modo per mille separatori per stringhe o numeri ... (come String.Format in c #)



Penso che troverai quello che ti serve lì :) stackoverflow.com/questions/610406/…
Jad

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

Risposte:


160

Aggiornamento (7 anni dopo)

Il riferimento citato nella risposta originale di seguito era sbagliato. C'è costruito in funzione di questo, che è esattamente ciò Kaiser suggerisce di seguito:toLocaleString

Quindi puoi fare:

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

Anche la funzione implementata di seguito funziona, ma semplicemente non è necessaria.

(Ho pensato che forse sarei stato fortunato e avrei scoperto che era necessario nel 2010, ma no. Secondo questo riferimento più affidabile , toLocaleString fa parte dello standard sin dalla terza edizione di ECMAScript [1999], che credo significhi sarebbe stato supportato fin da IE 5.5.)


Risposta originale

In base a questo riferimento non esiste una funzione incorporata per l'aggiunta di virgole a un numero. Ma quella pagina include un esempio di come codificarlo da soli:

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

Modifica: per passare dall'altra parte (converti la stringa con virgole in numero), potresti fare qualcosa del genere:

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

Lo apprezzo davvero molto // Ma come posso convertire quella stringa (con virgole) in un numero?
LostLord

questa funzione si interrompe per i numeri maggiori di 100.000
DevZer0

1
@ DevZer0 no non lo fa
Tallboy

funziona con javascript puro + singola regex sostituisce stackoverflow.com/a/44324879/681830
Val

4
utilizzare (1234567).toLocaleString().replace(/,/g," ",)per spazi tra migliaia
Fanky

122

Se si tratta di localizzare migliaia di separatori, delimitatori e separatori decimali, procedere con quanto segue:

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

Ci sono diverse opzioni che puoi usare (e anche le impostazioni locali con fallback):

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>

Dettagli sulla pagina delle informazioni su MDN .

Modifica: Commentor @I like Serena aggiunge quanto segue:

Per supportare i browser con impostazioni internazionali non inglesi in cui vogliamo ancora la formattazione inglese, usa value.toLocaleString('en'). Funziona anche per virgola mobile.


Questo non copre i numeri in virgola mobile .. puoi cambiare parseInt in parseFloat, ma se yourInt = "100,12" (virgola come separatore decimale) non funzionerà. Questo può essere risolto con una sostituzione (",", ".") .. ma fallirà di nuovo con "1.000,12". Quindi ... DEVI reinventare la ruota a volte. stackoverflow.com/a/2901298/1028304
Neiker

Non funziona bene. Utilizza la virgola mentre nel nostro locale lo spazio è comune per il separatore delle migliaia.
Josef Sábl,

1
Sarebbe più appropriato:Number(yourNumberOrString).toLocaleString()
Jonathan

2
Per supportare i browser con impostazioni internazionali non inglesi in cui vogliamo ancora la formattazione inglese, usa value.toLocaleString('en'). Funziona anche per virgola mobile.
Klaas van Aarsen

1
@ Serhiog.Lazin Cosa non funziona esattamente su Safari (e su quale sistema operativo e in quale versione)?
Kaiser

35

Aggiornato utilizzando il supporto look-behind in linea con le modifiche di ECMAScript2018.
Per la retrocompatibilità, scorri più in basso per vedere la soluzione originale.

Può essere usata un'espressione regolare, particolarmente utile quando si tratta di grandi numeri memorizzati come stringhe.

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

»Spiegazione dettagliata delle espressioni regolari (regex101.com) Diagramma di flusso


Questa risposta originale potrebbe non essere richiesta ma può essere utilizzata per la compatibilità con le versioni precedenti.

Tentando di gestirlo con una singola espressione regolare (senza callback) la mia attuale capacità mi fallisce per mancanza di un look-behind negativo in Javascript ... tuttavia ecco un'altra concisa alternativa che funziona nella maggior parte dei casi generali - tenendo conto di qualsiasi punto decimale ignorando le corrispondenze in cui l'indice della corrispondenza appare dopo l'indice di un punto.

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

»Spiegazione dettagliata delle espressioni regolari (regex101.com)

Diagramma di flusso


Questo diagramma di sintassi è stato creato su regex101.com?
Gerold Broser

cosa succede con i numeri con decimali?
Emiliano

Ricevo "Espressione regolare non valida: nome specificatore di gruppo non valido". Su React Native 0.59 si fa questo ma in realtà non dovrebbe influire su RegEx.
Joshua Pinter

@JoshuaPinter Sarà l'uso del look-behind che al momento della scrittura non è ancora supportato su tutte le piattaforme. Immagino che ti stia riferendo specificamente a iOS, poiché Safari continua a fallire anche per me. Per ora potrebbe essere meglio restare con la versione retrocompatibile. Stavo solo cercando di rendere la mia risposta a prova di futuro. caniuse.com/#search=lookbehind
Emissario

1
@Emissary Grazie per il suggerimento. Sì, è su React Native 0.59 / Android, che utilizza una versione relativamente precedente di JavaScriptCore (JSC). Riproverò dopo l'aggiornamento a React Native 0.60+, che include un aggiornamento a JSC.
Joshua Pinter

10

C'è un bel plugin per numeri jQuery: https://github.com/teamdf/jquery-number

Ti consente di modificare qualsiasi numero nel formato che preferisci, con opzioni per cifre decimali e caratteri separatori per decimali e migliaia:

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

Puoi usarlo direttamente all'interno dei campi di input, il che è più bello, usando le stesse opzioni come sopra:

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

Oppure puoi applicare a un intero set di elementi DOM utilizzando il selettore:

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

migliore soluzione imho
Michal

Non credo, aggiungendo un nuovo requisito di file con quasi 800 righe, è come uccidere una formica con una granata
Emiliano

6

Io uso questo:

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

fonte: collegamento


'123452343267.0505'.replace(/\B(?=(\d{3})+(?!\d))/g, ","); "123,452,343,267.0,505"- nota l'ultima virgola dopo il punto decimale.
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

Puoi usare javascript. sotto ci sono il codice, sarà solo acceptnumerico e unodot

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

DEMO JSFIDDLE



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
Potete per favore aggiungere anche qualche descrizione in modo che op e altre persone possano capire come questo codice risolva effettivamente il problema. Grazie
Punit Gajjar

prova con un nomber tra 1000 e 9999
Emiliano

1

Tutto quello che devi fare è davvero questo :

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

Purtroppo dipende dalla tua piattaforma. Alcuni hanno una toLocaleString()che non aggiunge le virgole o manca di altre funzionalità nello standard. È facile verificare la toLocaleStringpresenza ma non verificarne la conformità.
Hippietrail

prova con un numero compreso tra 1000 e 9999
Emiliano

0

Combinazione di soluzioni per reagire

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

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

handleOnChangeMonthlySalary(1000)```

0

Puoi usare ngx-format-field. È una direttiva per formattare il valore di input che apparirà nella vista. Non manipolerà il valore di input che verrà salvato nel backend. Vedi link qui !

Esempio:

component.html:

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

component.ts

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

Per vedere la demo: qui !


0

È possibile utilizzare la seguente funzione:

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


Non renderlo così confuso. basta usare toLocaleString (). Maggiori informazioni in developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Sajad Saderi

@sajadsaderi Uso anche toLocaleString () amico, ma questa funzione non mi dà molta flessibilità, quindi non devo avere a che fare con abbreviazioni regionali e qualcun altro potrebbe usarla poiché la definizione di questa funzione è identica a number_format () funzione di php.
jin_maxtor

-1

Non mi è piaciuta nessuna delle risposte qui, quindi ho creato una funzione che ha funzionato per me. Voglio solo condividere nel caso in cui qualcun altro lo trovi utile.

function getFormattedCurrency(num) {
    num = num.toFixed(2)
    var cents = (num - Math.floor(num)).toFixed(2);
    return Math.floor(num).toLocaleString() + '.' + cents.split('.')[1];
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.