# Tutorial :Regular expression for decimal number

### Question:

I need to validate a `textbox` input and can only allow decimal inputs like: `X,XXX` (only one digit before decimal sign and a precision of 3).

I'm using C# and try this `^[0-9]+(\.[0-9]{1,2})?\$`?

### Solution:1

``^[0-9]([.,][0-9]{1,3})?\$  ``

It allows:

``0  1  1.2  1.02  1.003  1.030  1,2  1,23  1,234  ``

BUT NOT:

``.1  ,1  12.1  12,1  1.  1,  1.2345  1,2345  ``

### Solution:2

There is an alternative approach, which does not have I18n problems (allowing ',' or '.' but not both): `Decimal.TryParse`.

Just try converting, ignoring the value.

``bool IsDecimalFormat(string input) {    Decimal dummy;    return Decimal.TryParse(input, out dummy);  }  ``

This is significantly faster than using a regular expression, see below.

(The overload of `Decimal.TryParse` can be used for finer control.)

Performance test results: Decimal.TryParse: 0.10277ms, Regex: 0.49143ms

Code (`PerformanceHelper.Run` is a helper than runs the delegate for passed iteration count and returns the average `TimeSpan`.):

``using System;  using System.Text.RegularExpressions;  using DotNetUtils.Diagnostics;    class Program {      static private readonly string[] TestData = new string[] {          "10.0",          "10,0",          "0.1",          ".1",          "Snafu",          new string('x', 10000),          new string('2', 10000),          new string('0', 10000)      };        static void Main(string[] args) {          Action parser = () => {              int n = TestData.Length;              int count = 0;              for (int i = 0; i < n; ++i) {                  decimal dummy;                  count += Decimal.TryParse(TestData[i], out dummy) ? 1 : 0;              }          };          Regex decimalRegex = new Regex(@"^[0-9]([\.\,][0-9]{1,3})?\$");          Action regex = () => {              int n = TestData.Length;              int count = 0;              for (int i = 0; i < n; ++i) {                  count += decimalRegex.IsMatch(TestData[i]) ? 1 : 0;              }          };            var paserTotal = 0.0;          var regexTotal = 0.0;          var runCount = 10;          for (int run = 1; run <= runCount; ++run) {              var parserTime = PerformanceHelper.Run(10000, parser);              var regexTime = PerformanceHelper.Run(10000, regex);                Console.WriteLine("Run #{2}: Decimal.TryParse: {0}ms, Regex: {1}ms",                                parserTime.TotalMilliseconds,                                 regexTime.TotalMilliseconds,                                run);              paserTotal += parserTime.TotalMilliseconds;              regexTotal += regexTime.TotalMilliseconds;          }            Console.WriteLine("Overall averages: Decimal.TryParse: {0}ms, Regex: {1}ms",                            paserTotal/runCount,                            regexTotal/runCount);      }  }  ``

### Solution:3

``\d{1}(\.\d{1,3})?    Match a single digit 0..9 Â«\d{1}Â»     Exactly 1 times Â«{1}Â»  Match the regular expression below and capture its match into backreference number 1 Â«(\.\d{1,3})?Â»     Between zero and one times, as many times as possible, giving back as needed (greedy) Â«?Â»     Match the character â€œ.â€ literally Â«\.Â»     Match a single digit 0..9 Â«\d{1,3}Â»        Between one and 3 times, as many times as possible, giving back as needed (greedy) Â«{1,3}Â»      Created with RegexBuddy  ``

Matches:
1
1.2
1.23
1.234

### Solution:4

In general, i.e. unlimited decimal places:

`^-?(([1-9]\d*)|0)(.0*[1-9](0*[1-9])*)?\$`

### Solution:5

I just found `TryParse()` has an issue that it accounts for thousands seperator. Example in En-US, 10,36.00 is ok. I had a specific scenario where the thousands seperator should not be considered and hence regex `\d(\.\d)` turned out to be the best bet. Of course had to keep the decimal char variable for different locales.

### Solution:6

In .NET, I recommend to dynamically build the regular expression with the decimal separator of the current cultural context:

``using System.Globalization;    ...    NumberFormatInfo nfi = NumberFormatInfo.CurrentInfo;  Regex re = new Regex("^(?\\d+("                      + Regex.Escape(nfi.CurrencyDecimalSeparator)                      + "\\d{1,2}))\$");  ``

You might want to pimp the regexp by allowing 1000er separators the same way as the decimal separator.

### Solution:7

As I tussled with this, TryParse in 3.5 does have NumberStyles: The following code should also do the trick without Regex to ignore thousands seperator.

``double.TryParse(length, NumberStyles.AllowDecimalPoint,CultureInfo.CurrentUICulture, out lengthD))  ``

Not relevant to the original question asked but confirming that TryParse() indeed is a good option.

Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Previous
Next Post »