Validate float number using RegEx in C#

38,410

Solution 1

Try this:

@"^[0-9]*(?:\.[0-9]*)?$"

You need to escape the period. And making the period and decimal part optional is probably a good idea.

If you need to handle negative values you can add -? before the first [0-9] in each pattern.

Update

Tested as follows:

var regex = new Regex(@"^[0-9]*(?:\.[0-9]*)?$");
Console.WriteLine(new bool[] {regex.IsMatch("blah"),
                              regex.IsMatch("12"),
                              regex.IsMatch(".3"),
                              regex.IsMatch("12.3"),
                              regex.IsMatch("12.3.4")});

results in

False 
True 
True 
True 
False 

Solution 2

I urge you to use Double.TryParse() method instead of regex validation. Using TryParse() let your application to be a bit more universal in terms of culture. When current culture changes, TryParse() will parse with no problem. Also TryParse() methods believed to have no bugs as they were tested by .net community.

But in case of regex your should change your validation expression hence it could be no relevant to new culture.

You can rewrite code like this:

private bool IsValidInput(string p)
{
    switch (this.Type)
    {
        case NumericTextBoxType.Float:
            double doubleResult;
            return double.TryParse(p, out doubleResult);
        case NumericTextBoxType.Integer:                    
        default:
            int intResult;
            return int.TryParse(p, out intResult);
    }
}

You can even add your own extension methods to make parsing part more elegant.

public static double? TryParseInt(this string source)
{
    double result;
    return double.TryParse(source, out result) ? result : (double?)null;
}

// usage
bool ok = source.TryParseInt().HasValue;

Solution 3

Check out the TryParse static methods you will find on double, float, and int.

They return true if the string can be parsed (by the Parse method).

Solution 4

[-+]?\d+(.\d+)?

The most simple regex for float. It it doesn't match the cases '123.' or '.123'.

Also, you should look on context culture:

CultureInfo ci = CultureInfo.CurrentCulture;
var decimalSeparator = ci.NumberFormat.NumberDecimalSeparator;
var floatRegex = string.Format(@"[-+]?\d+({0}\d+)?", decimalSeparator);

Solution 5

I tried the solution approved above, found that it will fail if user enters a dot only @"^[0-9]*(?:\.[0-9]*)?$".

So, I modified it to:

@"^[0-9]*(?:\.[0-9]+)?$"
Share:
38,410
John Smith
Author by

John Smith

Updated on July 09, 2022

Comments

  • John Smith
    John Smith almost 2 years

    I am trying to make a Numeric only TextBox in WPF and I have this code for it:

    void NumericTextBox_PreviewTextInput(object sender, TextCompositionEventArgs e)
    {
        e.Handled = !IsValidInput(e.Text);
    }
    
    private bool IsValidInput(string p)
    {
        switch (this.Type)
        {
            case NumericTextBoxType.Float:
                return Regex.Match(p, "^[0-9]*[.][0-9]*$").Success;
            case NumericTextBoxType.Integer:                    
            default:
                return Regex.Match(p, "^[0-9]*$").Success;                    
        }
    }
    
    // And also this!
    public enum NumericTextBoxType
    {
        Integer = 0, 
        Float = 1
    }
    

    When I set the type to Integer, it works well, but for Float, it does not.

    I can use so many NumericTextBox controls out there, but I was wondering why this one is not working?

  • gotqn
    gotqn about 9 years
    You need to escape the . like this: \.
  • Ohad Schneider
    Ohad Schneider over 8 years
    Nice work, but why the non-capturing group (?:)? Also, you don't need to escape a period in regex so the slash is redundant: ^[0-9]*(.[0-9]*)?$. One could also allow whitespace before and after the number: ^\s*[0-9]*(.[0-9]*)?\s*$ though the same could be achieved with a Trim call on the input string. Finally, it's very important to keep in mind that TryParse is the right answer - this is just for fun :)
  • Andrew Cooper
    Andrew Cooper over 8 years
    Ohad Schneider: The non-capturing group was just being pedantic. We don't need the value of the group, so there's no point capturing it.
  • Andrew Cooper
    Andrew Cooper over 8 years
    Ohad Schneider: As for the period, you do need to escape it if you want to match just a period. If you don't escape it, it will match any character, which is not what we want. Your suggested pattern would match 123X456, for example.
  • Ohad Schneider
    Ohad Schneider over 8 years
    My bad, I completely forgot period was the wildcard for any character (except \n). My regex-foo is rusty indeed...
  • Mr.B
    Mr.B over 5 years
    it will work with 0, whereas it is invalid value for double. It should be 0.0
  • Lavakusa
    Lavakusa over 5 years
    Awesome answer, you saved my day
  • peter70
    peter70 over 5 years
    Your option but a little bit shorter: private bool IsValid(string p) => this.IsFloatingPoint ? double.TryParse(p, out var d) : int.TryParse(p, out var i);