2

I'm trying to match a currency string that may or may not be suffixed with one of K, M, or Bn, and group them into two parts

Valid matches:

500 K       // Expected grouping: ["500", "K"]
900,000     // ["900,000", ""]
2.3 Bn      // ["2.3", "Bn"]
800M        // ["800", "M"]

ps: I know the matches first item in match output array is the entire match string, the above expected grouping in only an example

The Regex I've got so far is this:

/\b([-\d\,\.]+)\s?([M|Bn|K]?)\b/i

When I match it with a normal string, it does OK.

"898734 K".match(/\b([-\d\,\.]+)\s?([M|Bn|K]?)\b/i)
=> ["898734 K", "898734", "K"] // output

"500,000".match(/\b([-\d\,\.]+)\s?([M|Bn|K]?)\b/i)
=> ["500,000", "500,000", ""]

Trouble is, it also matches space in there

"89 8734 K".match(/\b([-\d\,\.]+)\s?([M|Bn|K]?)\b/i)
=> ["89 ", "89", ""]

And I'm not sure why. So I thought I'd add /g option in there to match entire string, but now it doesn't group the matches.

"898734 K".match(/\b([-\d\,\.]+)\s?([M|Bn|K]?)\b/gi)
=> ["898734 K"]

What change do I need to make to get the regex behave as expected?

4
  • what should be the result for "1 89 8734 K"? Commented Mar 7, 2017 at 10:36
  • @RomanPerekhrest - no match would be ideal Commented Mar 7, 2017 at 10:37
  • you're using word boundaries (\b) because this occurs mixed with other text? or are isolated lines? Commented Mar 7, 2017 at 10:43
  • @alebianco it's an isolated text, word boundaries not important / needed Commented Mar 7, 2017 at 10:47

2 Answers 2

1

You could use a different regular expression, which looks for some numbers, a comma or dot and some other numbers as well, some whitepspace and the wanted letters.

var array = ['500 K', '900,000', '2.3 Bn', '800M'],
    regex = /(\d+[.,]?\d*)\s*(K|Bn|M|$)/
    
array.forEach(function (a) {
    var m = a.match(regex);
    if (m) {
        m.shift();
        console.log(m);
    }    
});
.as-console-wrapper { max-height: 100% !important; top: 0; }

Sign up to request clarification or add additional context in comments.

Comments

0

You have a problem and want to use a regex to solve the problem. Now you have two problems...

Joke aside, I think you can achieve what you want to do without any regex:

"".join([c for i, c in enumerate(itertools.takewhile(lambda c: c.isdigit() or c in ',.', s))]), s[i+1:]

I tried this with s="560 K", s="900,000", etc and it seems to work.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.