55

I've spent half an hour trying to get this, maybe someone can come up with it quickly.

I need a regular expression that will match one or two digits, followed by an optional decmial point, followed by one or two digits.

For example, it should match these strings in their entirety:

3
33
.3
.33
33.3
33.33

and NOT match anything with more than 2 digits before or after the decmial point.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
Erix
  • 7,059
  • 2
  • 35
  • 61
  • 1
    Should it match the 33.33 in 133.33? – Jeremy Stein Jun 18 '09 at 18:19
  • No, there is no match if there are more than two digits before or after the decmial point. I think this is where I was confusing people. – Erix Jun 18 '09 at 18:21
  • 4
    A seriously good investment if you have more questions like this would be to get RegexBuddy. Incredible piece of software that lets you write/test regular expressions on the fly. – Brian Jun 18 '09 at 18:38

12 Answers12

78

EDIT: Changed to fit other feedback.

I understood you to mean that if there is no decimal point, then there shouldn't be two more digits. So this should be it:

\d{0,2}(\.\d{1,2})?

That should do the trick in most implementations. If not, you can use:

[0-9]?[0-9]?(\.[0-9][0-9]?)?

And that should work on every implementation I've seen.

Lee
  • 18,529
  • 6
  • 58
  • 60
  • This is how I would do it, except, use \d{0,2} or [0-9]{0,2} to match the given example .33 – Daniel Vandersluis Jun 18 '09 at 18:17
  • 2
    Which doesn't get .33. Try changing the first to \d{0,2}. – David Thornley Jun 18 '09 at 18:17
  • 1
    You also need to anchor the expression to satisfy the "and NOT match anything with more than 2 digits before or after the decmial point." requirement. – Daniel Vandersluis Jun 18 '09 at 18:20
  • 1
    In order to anchor it properly, I need to know whether to anchor on whitespace or beginning/end of line or whatever. Information I don't have, so I'll leave that as an exercise for the student. – Lee Jun 18 '09 at 18:22
  • Note that this one does match 333.33 (which I think you said it should only match up to two digits, but dont know if you mentioned if it should match more than two), it also matches 33.333 (three digits in the decimal area. – Brian Jun 18 '09 at 18:42
  • note this allows blank input, as the whole number and decimal parts are both optional. – northamerican Apr 25 '16 at 21:33
  • `3` matches... ? – Elijah Mock Aug 19 '21 at 00:23
  • WATCH OUT! this is not the correct answer !!! please see @jeremy-stein 's answer below.. that's why TEST, TEST & TEST, ladies (and gentleman)! – AlpharettaTechy Jun 18 '22 at 19:06
11
(?<![\d.])(\d{1,2}|\d{0,2}\.\d{1,2})?(?![\d.])

Matches:

  • Your examples
  • 33.

Does not match:

  • 333.33
  • 33.333
Jeremy Stein
  • 19,171
  • 16
  • 68
  • 83
  • This one may be better than the "Chosen" answer. – Brian Jun 18 '09 at 18:41
  • This absolutely correct answer, the original answer \d{0,2}(\.\d{1,2})? will not work for 123.45, as it will return 12, matching the first two digits, but this one is expecting no digit to exist before the first two digits and hence will not match 333.33 – AlpharettaTechy Jun 18 '22 at 18:43
8

To build on Lee's answer, you need to anchor the expression to satisfy the requirement of not having more than 2 numbers before the decimal.

If each number is a separate string, you can use the string anchors:

^\d{0,2}(\.\d{1,2})?$

If each number is within a string, you can use the word anchors:

\b\d{0,2}(\.\d{1,2})?\b
Daniel Vandersluis
  • 91,582
  • 23
  • 169
  • 153
5

You mentioned that you want the regex to match each of those strings, yet you previously mention that the is 1-2 digits before the decimal?

This will match 1-2 digits followed by a possible decimal, followed by another 1-2 digits but FAIL on your example of .33

\d{1,2}\.?\d{1,2}

This will match 0-2 digits followed by a possible deciaml, followed by another 1-2 digits and match on your example of .33

\d{0,2}\.?\d{1,2}

Not sure exactly which one you're looking for.

ahawker
  • 3,306
  • 24
  • 23
3

you can use

let regex = new RegExp( ^(?=[0-9.]{1,${maxlength}}$)[0-9]+(?:\.[0-9]{0,${decimal_number}})?$ );

where you can decide the maximum length and up to which decimal point you want to control the value

Use ES6 String interpolation to wrap the variables ${maxlength} and ${decimal_number}.

Darpan
  • 234
  • 3
  • 15
1
^(\d{0,2}\\.)?\d{1,2}$

\d{1,2}$ matches a 1-2 digit number with nothing after it (3, 33, etc.), (\d{0,2}\.)? matches optionally a number 0-2 digits long followed by a period (3., 44., ., etc.). Put them together and you've got your regex.

pp_
  • 3,435
  • 4
  • 19
  • 27
0
^\d{0,2}\.?\d{1,2}$
cpjolicoeur
  • 12,766
  • 7
  • 48
  • 59
0

A previous answer is mostly correct, but it will also match the empty string. The following would solve this.

^([0-9]?[0-9](\.[0-9][0-9]?)?)|([0-9]?[0-9]?(\.[0-9][0-9]?))$
0

Try this

\d{1,2}\.?(\.\d{1,2})?
fancyPants
  • 50,732
  • 33
  • 89
  • 96
0

Following is Very Good Regular expression for Two digits and two decimal points.

[RegularExpression(@"\d{0,2}(\.\d{1,2})?", ErrorMessage = "{0} must be a Decimal Number.")]
Keren Caelen
  • 1,466
  • 3
  • 17
  • 38
0

Try this

static onlyTwoIntegersAndTwoDecimals = /^\d{0,2}(\.\d{1,2})?$/;

and add Validators.max(10) for 0 - 10

Or

static onlyThreeIntegersAndTwoDecimals = /^\d{0,3}(\.\d{1,2})?$/;

and add Validators.max(100) for 0 - 100

-1

Corrected anwser

\d{1,}(\.\d{1,2})

tested in https://regexr.com/

matches with numbers with 2 decimals or just one, or numbers without decimals.

You can change the number or decimals you want by changing the number 2