tags:

views:

208

answers:

6

I need a regular expression in .net which

  • will only allow a maximum of two digits after "."
  • will only allow a maximum of two digits before "."
  • has a maximum length of 5
  • represents a number greater than 0
  • represents a number not greater than 100
  • has a number not greater than 11 after ".", like 5.11, 5.10, 5.03, 5.01, 5.06, etc (not 5.12, 5.2, 5.3)

Examples:

  • 1, 100, 100.00, 58, 58.10, 1.1, 0.02, .2, .02, 1.02, 11.11, 12.00, 01.09, 1.0 etc

Invalid numbers:

  • 1.12, 101.12, 100.1, 100.03, 100.65, etc. and all negative values
A: 

^(100(\.00?)?|\d\d?(\.(0\d|1[01]?))?)$

Asaph
A: 
^(?:\d{1,2}(?:\.(?:0?\d|1[01]))?|100)$
Lucero
Failed against 0.5
Havenard
0.5 is supposed to fail. 0.5 = 0.50 > 0.11 and we can't exceed 11 after the decimal place.
Asaph
When I say "failed" I meant it returned valid when it shouldn't. You placed a ? in the wrong place there.
Havenard
A: 

MaskedEditValidator can also be used, if you want to limit the value with MaximumValue and MinimumValue

<ajaxToolkit:MaskedEditValidator
ControlExtender="MaskedEditExtender2"
ControlToValidate="TextBox2" 
IsValidEmpty="False" 
MaximumValue="100" 
InvalidValueMessage="Number is invalid"
MaximumValueMessage="Number > 100"
MinimumValueMessage="Number < 0"
MinimumValue="0" 
Display="Dynamic" 
TooltipMessage="Input a number: 0 up to 100.00"/>

take a look....http://www.asp.net/AJAX/AjaxControlToolkit/Samples/MaskedEdit/MaskedEdit.aspx

Muhammad Akhtar
A: 
"^100(\.00?)?|\d\d?(\.(1[01]?|0\d?))?$"
Havenard
it does not allow 100.00
Avinash
Wasn't the maximum length 5?
Havenard
+1  A: 

this regex is based on the one from Xetius:

^(100(?:\.00?)?|\d{1,2}(?:\.(?:11|10|0\d|0|1))?)$

below is the code how I Tested it:

class Program
{
    const string Pattern = @"^(100(?:\.00?)?|\d{1,2}(?:\.(?:11|10|0\d|0|1))?)$";
    static void Main(string[] args)
    {
        for (int before = 0; before < 100; before++)
        {
            Test(before.ToString());
            for (int after = 0; after < 12; after++)
            {
                Test(string.Format("{0}.{1:d2}", before, after));
                Test(string.Format("{0:d2}.{1:d2}", before, after));
                Test(string.Format(".{0:d2}", after));
            }
            Test(string.Format("{0}.{1:d}", before, 0));
            Test(string.Format("{0:d2}.{1:d}", before, 1));
        }
        // Special cases:
        Test("100");
        Test("100.0");
        Test("100.00");

        // intended to fail
        Test("00.20");
        Test("00.12");
        Test("00.00x");
        Test("000.00");
        Console.WriteLine("done.");
        Console.ReadLine();
    }

    private static void Test(string input)
    {
        Regex r = new Regex(Pattern);
        if (!r.IsMatch(input))
        {
            Console.WriteLine("no match: " + input);
        }
    }
}

Edit:

  • Tweaked the regex so that 100.0 also works
  • added a comment for the tests intended to fail

Edit2:

  • Added Test for .00 - .11 and was surprised that the regex already matched them. Thanks to Xetius
Thomas Schreiner
Failed against 0.5
Havenard
so what? 0.5 is supposed to fail because you can't have a number greater than 1 as the first digit after the decimal place
Asaph
The real question here is, what does 0.5 mean: 0.50 or 0.05?
Thomas Schreiner
When I say "failed" I mean it returned valid when it shouldn't.
Havenard
0.5 means 0.5. 0.05 is a completely different number. That is like confusing 5 and 50
Xetius
From the supplied data (Which Im sure has changed) it has to match with .01 to .11 meaning that the whole number is optional.
Xetius
+2  A: 
^100\.00|\d{1,2}\.(?:11|10|0\d)$

OK, was simpler than I thought.

^100(?:\.00?)?$|^(?:\d{1,2})?(?:\.(?:1|11|10|0\d?))?$

This matches the new set of data. It also matches .0 at the moment.

Xetius
Not so fast. This regular expression doesn't match "100", "100.0", "1.1", "1.0"
Asaph