0

I have a regex /\B(?=(\d{3})+(?!\d))/g which format the number into thousand's seperator. Like when you enter 752892, it gives me 752,892. I want to add to this regex not to allow decimal value and alphabets. How can we achieve this.

const THOUSANDS_SEPARATOR = ','
let  i= (value || '').toString();
    i= integer.replace(/\B(?=(\d{3})+(?!\d))/g, this.THOUSANDS_SEPARATOR);
user1015388
  • 1,283
  • 4
  • 25
  • 45
  • 1
    [...now you have two problems](https://softwareengineering.stackexchange.com/questions/223634/what-is-meant-by-now-you-have-two-problems). Seriously, while this regexp is smart (\B matches all the locations in the original string followed by 3*n digits), you should just check that you're given a number (integer? decimal?) and format it using a proper solution linked here: [How to print a number with commas as thousands separators in JavaScript](https://stackoverflow.com/questions/2901102/how-to-print-a-number-with-commas-as-thousands-separators-in-javascript) – Nickolay Jun 06 '18 at 22:13
  • @Nickolay, thanks. Let me try it. Basically I think I need to replace \B with which accepts numbers, I guess – user1015388 Jun 07 '18 at 00:03
  • Isn't there a number format functions for this already all over SO? – hungrykoala Jun 07 '18 at 00:37
  • Not sure if there is any – user1015388 Jun 07 '18 at 12:01
  • I don't think you should be trying to extend this regexp. First check if you the input is valid ("not to allow decimal value and alphabets" is not specific enough to suggest a concrete solution), then format the number. – Nickolay Jun 07 '18 at 16:35

1 Answers1

1

This one is tricky. A possible solution is to add the bad cases to an alternation that is skipped.

One way to do so is by using the backtracking control verbs *SKIP *FAIL:

.*[a-zA-Z.].*(*SKIP)(*FAIL)|\B(?=(\d{3})+(?!\d))

Demo

Another way is to use a capture group for the good cases along with a .replace callback.

Here is a JavaScript sample that shows how it works with a regex flavor that does not support those backtracking verbs:

const regex = /.*[a-zA-Z.].*|\B(?=(\d{3})+(?!\d))/gm;
const str = `
123
1234
12345
752892
Bad
123123456.000000
12a3123456.0000000000
123456.12345a12345`;

const result = str.replace(regex, function(m, group1) {
    if (group1) return ",";
    return "invalid";//m;
});

console.log('Substitution result: ', result);
wp78de
  • 18,207
  • 7
  • 43
  • 71
  • this is nice. But in the demo link why is that I see the last few results even though it has decimals after we apply the regex – user1015388 Jun 08 '18 at 14:00
  • @user1015388 you mean "see .. values with decimals" in the substitution section? Because these values are not modified. It depends on the language you use to treat non-matches, i.e. in my JavaScript sample I use a replace callback and ditch those values. Always specify the language or tool when you ask a regex question. – wp78de Jun 08 '18 at 15:37