davis
davis

Reputation: 381

Regex - Get only decimal number from string

I have a regex below:

(?<=Bonus)[\s+][\$][\s+]?(\d(?:[d{0,2}.\s]*\d)?)

This gets the expected outcomes, however, sometimes I also get one extra digit.

For example, this is the context:

Bonus $0. 01 87% 88% 89% 90% 92% 93% 94%

So my regex gets 0 . 01 just fine, but not every time. When there are more lines like below:

Bonus $0. 01 87% 88% 89% 90% 92% 93% 94%
...
Bonus $0. 11 87% 88% 89% 90% 92% 93% 94%
...
Bonus $0. 15 87% 88% 89% 90% 92% 93% 94%
...

sometimes it gets one extra digit from string:

0. 01
0. 11 8
0. 15

OR sometimes miss 1 decimal place:

0. 1 (but it should be 0. 15)

Expected outcome will be always a number with 2 decimal places. There may or may not be whitespace(s) in numbers. Could be like 0.01, 0. 01, or even 0.(more whitespaces) 01...

What's wrong with my current regex?

Upvotes: 1

Views: 154

Answers (3)

The fourth bird
The fourth bird

Reputation: 163207

If you capture the digits in a group, you don't need a lookbehind for Bonus, you can match it instead.

Note that in your pattern, this part is a character class [d{0,2}.\s] that matches any of the listed chars, including a d char.

You could also omit the superfluous square brackets.


To match only digits with a decimal part (which seem to be always 2 digits):

\bBonus\s+\$\s*(\d+\.\s*\d{2})\b

The pattern matches:

  • \bBonus\s+\$\s* Match Bonus, 1+ whitespace chars, $ char and optional whitespace chars
  • ( Capture group 1
    • \d+\.\s*\d{2} Match 1+ digits, a dot, optional whitespace chars and 2 digits
  • ) Close group 1
  • \b A word boundary to prevent a partial match

Regex demo

Upvotes: 1

Scott Weaver
Scott Weaver

Reputation: 7351

You are using too many character classes, in particular this one: [d{0,2}.\s] - you can't quantify things inside a character class, so this isn't doing what it should be doing. (you can also get rid of some other ones, like \s+ instead of [\s+])

If I understand correctly that you want to match 2 digits after the decimal, spaces being possibly interspersed, this might work:

(?<=Bonus)\s*\$\s*\d*\.(\s*\d\s*){0,2}

https://regex101.com/r/nDj8Gd/1/

Upvotes: 0

Philipp Ape
Philipp Ape

Reputation: 631

That matches everything correctly: (?<=Bonus)[\s+][\$][\s+]?(\d*\.\s*\d{2}?)

Upvotes: 2

Related Questions