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?

Community
  • 1
  • 1
Alex L.
  • 416
  • 1
  • 4
  • 14
  • 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. – kelegorm Aug 11 '15 at 06:54

6 Answers6

62

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 
jamesdlin
  • 81,374
  • 13
  • 159
  • 204
kelegorm
  • 935
  • 7
  • 12
  • 2
    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]},"));` – Alex L. Aug 11 '15 at 16:43
  • Thanks! Can you please explain how it works? – batuhankrbb Aug 09 '21 at 03:34
  • It's nothing special, usual Regular Expression stuff. You can read any book about that. I have read that one: https://www.oreilly.com/library/view/mastering-regular-expressions/0596528124/ – kelegorm Sep 27 '21 at 09:37
14
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)
Clyde Santos
  • 305
  • 2
  • 6
3

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]},');
Rushi Dave
  • 37
  • 3
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.

  • 1
    Wouldn't this produce something like `12,423,`, adding a comma at the end? – Izzy Aug 11 '15 at 06:38
  • 1
    No, it doesn't add an extra comma at the end of the new number – Dungeonfire Aug 11 '15 at 06:39
  • 1
    Ah okay, and yeah I just tested it and you're right. GL OP! – Izzy Aug 11 '15 at 06:40
  • 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. – Alex L. Aug 11 '15 at 16:41
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();
    
  }
}
zex_rectooor
  • 692
  • 7
  • 26
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);