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



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

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.


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


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

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


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


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


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

Tout ce que vous avez à faire est vraiment ceci :

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

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

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 !


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


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];
}
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.