Dart how to add commas to a string number
Asked Answered
C

7

24

I'm trying to adapt this: Insert commas into number string to work in dart, but no luck.

either one of these don't work:

print("1000200".replaceAllMapped(new RegExp(r'/(\d)(?=(\d{3})+$)'), (match m) => "${m},"));
print("1000300".replaceAll(new RegExp(r'/\d{1,3}(?=(\d{3})+(?!\d))/g'), (match m) => "$m,"));

Is there a simpler/working way to add commas to a string number?

Camorra answered 11/8, 2015 at 0:25 Comment(1)
In first adaptation you miss $&, replacer. It's for JS only, without this replacer expression doesn't work. We should change expression to a little, look at my answer bellow.Heteronym
H
66

You just forgot get first digits into group. Use this short one:

'12345kWh'.replaceAllMapped(RegExp(r'(\d{1,3})(?=(\d{3})+(?!\d))'), (Match m) => '${m[1]},')

Look at the readable version. In last part of expression I added checking to any not digit char including string end so you can use it with '12 Watt' too.

RegExp reg = RegExp(r'(\d{1,3})(?=(\d{3})+(?!\d))');
String Function(Match) mathFunc = (Match match) => '${match[1]},';

List<String> tests = [
  '0',
  '10',
  '123',
  '1230',
  '12300',
  '123040',
  '12k',
  '12 ',
];

for (String test in tests) {    
  String result = test.replaceAllMapped(reg, mathFunc);
  print('$test -> $result');
}

It works perfectly:

0 -> 0
10 -> 10
123 -> 123
1230 -> 1,230
12300 -> 12,300
123040 -> 123,040
12k -> 12k
12  -> 12 
Heteronym answered 11/8, 2015 at 6:51 Comment(3)
Kelegorm, AWESOME! thank you so much! that worked. Here is my working code: print("1000200".replaceAllMapped(new RegExp(r'(\d{1,3})(?=(\d{3})+(?!\d))'), (Match m) => "${m[1]},"));Camorra
Thanks! Can you please explain how it works?Infuscate
It's nothing special, usual Regular Expression stuff. You can read any book about that. I have read that one: oreilly.com/library/view/mastering-regular-expressions/…Heteronym
W
18
import 'package:intl/intl.dart';

var f = NumberFormat("###,###.0#", "en_US");
print(f.format(int.parse("1000300")));

prints 1,000,300.0 check dart's NumberFormat here

The format is specified as a pattern using a subset of the ICU formatting patterns.

  • 0 A single digit
  • # A single digit, omitted if the value is zero
  • . Decimal separator
  • - Minus sign
  • , Grouping separator
  • E Separates mantissa and expontent
  • + - Before an exponent, to say it should be prefixed with a plus sign.
  • % - In prefix or suffix, multiply by 100 and show as percentage
  • ‰ (\u2030) In prefix or suffix, multiply by 1000 and show as per mille
  • ¤ (\u00A4) Currency sign, replaced by currency name
  • ' Used to quote special characters
  • ; Used to separate the positive and negative patterns (if both present)
Wyrick answered 27/7, 2021 at 17:32 Comment(1)
I don't understand why this isn't the top answer. Dart has a class for this purpose, that's clear and readable. No regex needed.Variegate
R
4

Let's take the example amount 12000. now our expected amount should be 12,000.00

so, the solution is

double rawAmount = 12000;
String amount = rawAmount.toStringAsFixed(2).replaceAllMapped(RegExp(r'(\d{1,3})(?=(\d{3})+(?!\d))'), (Match m) => '${m[1]},');

or if you don't want to add .00 then, we just need to use toString() instead of toStringAsFixed().

String amount = rawAmount.toString().replaceAllMapped(RegExp(r'(\d{1,3})(?=(\d{3})+(?!\d))'), (Match m) => '${m[1]},');
Redshank answered 10/11, 2021 at 10:29 Comment(0)
P
2

Try the following regex: (\d{1,3})(?=(\d{3})+$)

This will provide two backreferences, and replacing your number using them like $1,$2, will add commas where they are supposed to be.

Pietrek answered 11/8, 2015 at 6:20 Comment(4)
Wouldn't this produce something like 12,423,, adding a comma at the end?Darling
No, it doesn't add an extra comma at the end of the new numberPietrek
Ah okay, and yeah I just tested it and you're right. GL OP!Darling
Dungeonfire >> I tried adapting your suggestion, but no dice. Maybe is my limited experience w/replaceAll. print("100030".replaceAll(new RegExp(r'(\d{1,3})(?=(\d{3})+$)'), '$1,$2'); That didn't work..neither using replaceAllMapped.Camorra
H
0
extension on int {
  String get priceString {
    final numberString = toString();
    final numberDigits = List.from(numberString.split(''));
    int index = numberDigits.length - 3;
    while (index > 0) {
      numberDigits.insert(index, ',');
      index -= 3;
    }
    return numberDigits.join();
    
  }
}
Howie answered 20/7, 2022 at 13:9 Comment(0)
S
0

because in case of type double, the output will change based on the way, so check them.

If you need to format integer then any way works.

//1233.45677 => 1,233.4567    
        String num='1233.45677';
        RegExp pattern = RegExp(r'(?<!\.\d*)(\d)(?=(?:\d{3})+(?:\.|$))');
        String Function(Match) replace = (m) => '${m[1]},';
        print(num..replaceAllMapped(pattern, replace));
    
//1233.45677 => 1,233.456,7

    String num='1233.45677';
    pattern = RegExp(r'(\d{1,3})(?=(\d{3})+(?!\d))');
    String Function(Match) replace = (m) => '${m[1]},';
    print(num..replaceAllMapped(pattern, replace));

//1233.45677 => 1,233.46
//after import intl package, to be able to use NumberFormat
       
    String num='1233.45677';
    var f = NumberFormat("###,###.0#", "en");
    print(f.format(double.parse()));

if the number is in String type.

    //in case of int data type
int.parse(num);
    //in case of double data type
double.parse(num);
Scintillation answered 21/12, 2022 at 20:4 Comment(0)
P
0

I recently came across your solution on Stack Overflow for formatting numbers in a readable way, and I wanted to thank you for sharing it. I implemented it in my project and it worked perfectly.

However, while working with the solution, I realized it could be made a bit more convenient and portable for use throughout the entire project without having to export the function every time it's needed. That's why I decided to encapsulate it within a Dart extension.

I created an extension called FinantialFormat that contains the formatToFinancial method, which accepts an optional parameter to include the money symbol if needed. This way, I can now easily use this functionality anywhere in the project simply by calling formatToFinancial() on a string.

Of course, I want to give you full credit for the original solution. Your approach was very helpful, and I simply tried to improve the way of using it in my project.

If you have any suggestions or comments regarding this, I'd be happy to hear them!


extension FinancialFormat on String {
  String mathFunc(Match match) => '${match[1]},';

  String formatToFinancial({
    bool isMoneySymbol = false,
  }) {
    final RegExp reg = RegExp(r'(\d{1,3})(?=(\d{3})+(?!\d))');

    final formatNumber = replaceAllMapped(reg, mathFunc);
    if (isMoneySymbol) {
      return '\$ $formatNumber';
    }
    return formatNumber;
  }
}

Example to use it:

TitleH1(
          text: bank!.amount.toString().formatToFinancial(
                isMoneySymbol: true,
              ),
          color: colorScheme.onBackground,
          fontSize: 30.0,
        ),
Posset answered 4/5 at 16:55 Comment(1)
This does not provide an answer to the question. Once you have sufficient reputation you will be able to comment on any post; instead, provide answers that don't require clarification from the asker. - From ReviewAirlike

© 2022 - 2024 — McMap. All rights reserved.