Séparateur de milliers de Javascript / format de chaîne [dupliquer]

96

Existe-t-il une fonction en Javascript pour le formatage des nombres et des chaînes?

Je cherche un moyen de séparer les milliers de chaînes ou de nombres ... (comme String.Format In c #)

LostLord
la source
Je pense que vous trouverez ce dont vous avez besoin là-dedans :) stackoverflow.com/questions/610406/…
Jad
How to print a number with commas as thousands separators in JavaScript: stackoverflow.com/questions/2901102/…
Adrien Be

Réponses:

160

Mise à jour (7 ans plus tard)

La référence citée dans la réponse originale ci-dessous était erronée. Il y a une fonction intégrée pour cela, qui est exactement ce que Kaiser suggère ci-dessous:toLocaleString

Vous pouvez donc faire:

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

La fonction implémentée ci-dessous fonctionne également, mais n'est tout simplement pas nécessaire.

(Je pensais que j'avoir de la chance et de savoir qu'il était de retour nécessaire en 2010, mais non. Selon cette référence plus fiable , toLocaleString a fait partie de la norme depuis ECMAScript 3e édition [1999], que je crois signifie qu'il aurait été pris en charge dès IE 5.5.)


Réponse originale

Selon cette référence, il n'y a pas de fonction intégrée pour ajouter des virgules à un nombre. Mais cette page comprend un exemple de la façon de la coder vous-même:

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

Edit: Pour aller dans l'autre sens (convertir une chaîne avec des virgules en nombre), vous pouvez faire quelque chose comme ceci:

parseFloat("1,234,567.89".replace(/,/g,''))
Tim Goodman
la source
Vraiment vraiment l'apprécier // Mais comment puis-je convertir cette chaîne (avec des virgules) en un nombre?
LostLord
cette fonction est interrompue pour les nombres supérieurs à 100000
DevZer0
1
@ DevZer0 non, ce n'est pas le cas
Tallboy
fonctionne avec javascript pur + regex unique remplace stackoverflow.com/a/44324879/681830
Val
4
utiliser (1234567).toLocaleString().replace(/,/g," ",)pour les espaces entre des milliers
Fanky
122

S'il s'agit de localiser des séparateurs de milliers, des délimiteurs et des séparateurs décimaux, procédez comme suit:

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

Il existe plusieurs options que vous pouvez utiliser (et même des paramètres régionaux avec des solutions de secours):

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>

Détails sur la page d'informations MDN .

Edit: Commentor @J'aime Serena ajoute ce qui suit:

Pour prendre en charge les navigateurs avec des paramètres régionaux non anglais où nous voulons toujours un formatage anglais, utilisez value.toLocaleString('en'). Fonctionne également pour la virgule flottante.

kaiser
la source
Cela ne couvre pas les nombres flottants .. vous pouvez changer parseInt en parseFloat, mais si yourInt = "100,12" (virgule comme séparateur décimal) cela échouera. Cela peut être corrigé avec un remplacement (",", ".") .. mais échouera à nouveau avec "1.000,12". Alors ... Vous DEVEZ parfois réinventer la roue. stackoverflow.com/a/2901298/1028304
neiker
Cela ne fonctionne pas bien. Utilise la virgule dans notre espace local est commun pour le séparateur de milliers.
Josef Sábl
1
Ce serait plus approprié:Number(yourNumberOrString).toLocaleString()
Jonathan
2
Pour prendre en charge les navigateurs avec des paramètres régionaux non anglais où nous voulons toujours un formatage anglais, utilisez value.toLocaleString('en'). Fonctionne également pour la virgule flottante.
Klaas van Aarsen
1
@ Serhiog.Lazin Qu'est-ce qui ne fonctionne pas exactement sur Safari (et sur quel OS et dans quelle version)?
kaiser le
35

Mise à jour avec le support look-behind conformément aux modifications d'ECMAScript2018.
Pour une compatibilité descendante, faites défiler plus bas pour voir la solution d'origine.

Une expression régulière peut être utilisée - particulièrement utile pour traiter de grands nombres stockés sous forme de chaînes.

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

»Explication verbeuse des expressions régulières (regex101.com) représentation schématique


Cette réponse originale peut ne pas être requise mais peut être utilisée pour la compatibilité ascendante.

Tenter de gérer cela avec une seule expression régulière (sans rappel) ma capacité actuelle me fait défaut faute d'un regard négatif en Javascript ... néanmoins, voici une autre alternative concise qui fonctionne dans la plupart des cas généraux - en tenant compte de n'importe quel point décimal en ignorant les correspondances où l'index de la correspondance apparaît après l'index d'une période.

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

»Explication verbeuse des expressions régulières (regex101.com)

représentation schématique

Émissaire
la source
Ce diagramme de syntaxe a-t-il été créé sur regex101.com?
Gerold Broser
que se passe-t-il avec les nombres décimaux?
Emiliano
J'obtiens "Expression régulière non valide: nom de spécificateur de groupe non valide". Sur React Native 0.59 faire cela mais cela ne devrait vraiment pas affecter RegEx.
Joshua Pinter
@JoshuaPinter Ce sera l'utilisation du look-behind qui au moment de la rédaction n'est pas encore pris en charge sur toutes les plates-formes. Je suppose que vous faites référence spécifiquement à iOS - car Safari échoue toujours pour moi aussi. Il peut être préférable de s'en tenir à la version rétrocompatible pour le moment. J'essayais juste de pérenniser ma réponse. caniuse.com/#search=lookbehind
Emissaire
1
@Emissary Merci pour le tuyau. Oui, c'est sur React Native 0.59 / Android, qui utilise une version relativement plus ancienne de JavaScriptCore (JSC). Je réessayerai après la mise à jour vers React Native 0.60+, qui inclut une mise à jour du JSC.
Joshua Pinter le
10

Il y a un joli plugin de numéro jQuery: https://github.com/teamdf/jquery-number

Il vous permet de changer n'importe quel nombre dans le format que vous aimez, avec des options pour les chiffres décimaux et des séparateurs pour les décimaux et les milliers:

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

Vous pouvez l'utiliser directement dans les champs de saisie, ce qui est plus agréable, en utilisant les mêmes options que ci-dessus:

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

Ou vous pouvez appliquer à tout un ensemble d'éléments DOM à l'aide du sélecteur:

$('span.number').number(true, 2);
qdev
la source
meilleure solution à mon humble avis
Michal
Je ne pense pas, en ajoutant une nouvelle exigence de fichier avec près de 800 lignes, c'est comme tuer une fourmi avec un granade
Emiliano
6

J'utilise ceci:

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

source: lien

Abhishek Goel
la source
'123452343267.0505'.replace(/\B(?=(\d{3})+(?!\d))/g, ","); "123,452,343,267.0,505"- remarquez la dernière virgule après la virgule décimale.
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;
}   
h. foroutan
la source
3

Vous pouvez utiliser javascript. ci-dessous sont le code, il sera uniquement acceptnumérique et undot

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

DÉMO JSFIDDLE

Awtszs
la source
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>
Ricardo
la source
6
Pouvez-vous s'il vous plaît ajouter une description afin que op et d'autres personnes puissent comprendre comment ce code résout réellement le problème. Merci
Punit Gajjar
essayez avec un nomber entre 1000 et 9999
Emiliano
1

PHP.js a une fonction pour faire cela appelée number_format . Si vous êtes familier avec PHP, cela fonctionne exactement de la même manière .

istvanp
la source
Le premier lien suit l'implémentation JS de la version PHP. C'est utile.
o_nix
1

Tout ce que vous avez à faire est vraiment ceci :

123000.9123.toLocaleString()
//result will be "123,000.912"
Ezeewei
la source
Malheureusement, cela dépend de votre plateforme. Certains ont un toLocaleString()qui n'ajoute pas les virgules, ou manque d'autres fonctionnalités dans la norme. Il est facile de vérifier la toLocaleStringprésence mais pas de vérifier sa conformité.
hippietrail
essayer avec un nombre entre 1000 et 9999
Emiliano
0

Combinaison de solutions pour réagir

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

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

handleOnChangeMonthlySalary(1000)```
Chinedu Ofor
la source
0

Vous pouvez utiliser ngx-format-field. C'est une directive pour formater la valeur d'entrée qui apparaîtra dans la vue. Il ne manipulera pas la valeur d'entrée qui sera enregistrée dans le backend. Voir le lien ici !

Exemple:

component.html:

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

component.ts

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

Pour voir la démo: ici !

moumita kundu
la source
0

Vous pouvez utiliser la fonction suivante:

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

jin_maxtor
la source
Ne rendez pas les choses si déroutantes. utilisez simplement toLocaleString (). Plus d'informations dans developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/...
Sajad Saderi
@sajadsaderi J'utilise aussi toLocaleString () friend, mais cette fonction ne me donne pas beaucoup de flexibilité, donc je n'ai pas à m'occuper des abréviations régionales et quelqu'un d'autre pourrait l'utiliser puisque la définition de cette fonction est identique au number_format () fonction de php.
jin_maxtor
-1

Je n'ai aimé aucune des réponses ici, j'ai donc créé une fonction qui a fonctionné pour moi. Je veux juste partager au cas où quelqu'un d'autre le trouverait utile.

function getFormattedCurrency(num) {
    num = num.toFixed(2)
    var cents = (num - Math.floor(num)).toFixed(2);
    return Math.floor(num).toLocaleString() + '.' + cents.split('.')[1];
}
Spencer Sullivan
la source