locked
regular expression for decimal range from -23 to +23 in 0.5 increments. RRS feed

  • Question

  • -23 to +23 in 0.5 increments

    Valid values = 3, -2.5, -2, -1.5, -0.5, 0, 0.5, 1, 1.5

    Not valid = 2.2,-21.3

    Tuesday, October 25, 2011 7:00 PM

Answers

  • @Ron, Actually I did include -23 and +23 and -23.0 and +23.0 using the prefix:

    ^-?(23(\.0)?

    @Link, No please don't use double for things that need to be precise. If our case were to accept 10.1, it would break instantly, as .1 cannot correctly be expressed in a double format.

    If needed suffix the %0.5 with an M to ensure the 0.5 stays in decimal  format:

    using System;
    using System.Globalization;
    
    namespace ValidateDecimal
    {
        class Program
        {
            static void Main(string[] args)
            {
                string values = "3, -2.5, -2, -1.5, -0.5, 0, 0.5, 1, 1.5, 2.2, -21.3";
    
                foreach (string s in values.Split(','))
                    Console.WriteLine("Value={0}, IsValid={1}", s, Validate(s));
    
                Console.ReadKey();
            }
    
            static bool Validate(string s)
            {
                decimal d = -999;
                if (decimal.TryParse(s, NumberStyles.Number, CultureInfo.InvariantCulture, out d))
                    return d >= -23 && d <= 23 && d % 0.5M == 0;
                return d != -999;
            }
        }
    }
    

    a different approach is to multiply the result by 10, then use mod 5, to forego the 0.5M requirement.


    My blog: http://blog.jessehouwing.nl/
    • Proposed as answer by Jesse HouwingMVP Wednesday, October 26, 2011 5:23 PM
    • Marked as answer by Paul Zhou Wednesday, November 2, 2011 5:08 AM
    Wednesday, October 26, 2011 5:23 PM

All replies

  • On Tue, 25 Oct 2011 19:00:44 +0000, VjDT wrote:
     
    >
    >
    >-23 to +23 in 0.5 increments
    >
    >Valid values = 3, -2.5, -2, -1.5, -0.5, 0, 0.5, 1, 1.5
    >
    >Not valid = 2.2,-21.3
     
    You might be able to simplify this, but it should work:
     
    -?\b(?:(?:2[0-2]|[01]?\d)\.[05])\b|(?<!\.)\b(?:(?:2[0-3]|[01]?\d))\b(?!\.)
     

    Ron
    Tuesday, October 25, 2011 7:54 PM
  • Or simply use a mathematical solution, which is probably easier to read and quite a bit faster:

    decimal value = 0;

    if (decimal.TryParse(input, .... , out value))
        return value >= -23 && value <= 23 && value %0.5 = 0; 

     

    Or the simplified version of the above expression:

    ^-?(23(\.0)?|(2[0-2]|1?[0-9])(\.[05])?)$

    Which also allows: 3.0, or

    ^-?(23|(2[0-2]|1?[0-9])(\.[5])?)$

    Which does allow 3.5, but disallows 3.0


    My blog: http://blog.jessehouwing.nl/
    Tuesday, October 25, 2011 10:09 PM
  • Although your math solution is probably the best, I note that neither of our regexes will accept 23.0 or  -23.0.  Since I am into minimizing my time in developing the solution, I would just add that on as an alternative:

    -?\b(?:(?:2[0-2]|[01]?\d)\.[05])\b|(?<!\.)\b(?:(?:2[0-3]|[01]?\d))\b(?!\.)|-?\b23\.0\b

    And again, it can be simplified.

     


    Ron
    Tuesday, October 25, 2011 11:22 PM
  • And here is a more compact version of the above:

    -?(?<!\.)\b(?:(?:23(?:\.0)?)|(?:(?:2[0-2]|[1]?\d)(?:\.[05])?))\b(?!\.)

    Or with free-spacing enabled:

    -?(?<!\.)\b
       (?:(?:23(?:\.0)?)|
         (?:(?:2[0-2]|[1]?\d)
           (?:\.[05])?))
             \b(?!\.)

     

    I note a particular difference between your regex and mine in that mine should be able to detect the value any place in the string.  I don't know if that is important to the OP or not.


    Ron
    Wednesday, October 26, 2011 1:20 AM
  • @Jesse, It is more appropriate to use the double value type. I think that "value % 0.5" is incorrect for decimal type.

    using System;
    using System.Globalization;
    
    namespace ValidateDecimal
    {
        class Program
        {
            static void Main(string[] args)
            {
                string values = "3, -2.5, -2, -1.5, -0.5, 0, 0.5, 1, 1.5, 2.2, -21.3";
    
                foreach (string s in values.Split(','))
                    Console.WriteLine("Value={0}, IsValid={1}", s, Validate(s));
    
                Console.ReadKey();
            }
    
            static bool Validate(string s)
            {
                double d = -999;
                if (double.TryParse(s, NumberStyles.Number, CultureInfo.InvariantCulture, out d))
                    return d >= -23 && d <= 23 && d % 0.5 == 0;
                return d != -999;
            }
        }
    }
    
    

    Kind regards,

     


    aelassas.free.fr
    Wednesday, October 26, 2011 4:49 PM
  • @Ron, Actually I did include -23 and +23 and -23.0 and +23.0 using the prefix:

    ^-?(23(\.0)?

    @Link, No please don't use double for things that need to be precise. If our case were to accept 10.1, it would break instantly, as .1 cannot correctly be expressed in a double format.

    If needed suffix the %0.5 with an M to ensure the 0.5 stays in decimal  format:

    using System;
    using System.Globalization;
    
    namespace ValidateDecimal
    {
        class Program
        {
            static void Main(string[] args)
            {
                string values = "3, -2.5, -2, -1.5, -0.5, 0, 0.5, 1, 1.5, 2.2, -21.3";
    
                foreach (string s in values.Split(','))
                    Console.WriteLine("Value={0}, IsValid={1}", s, Validate(s));
    
                Console.ReadKey();
            }
    
            static bool Validate(string s)
            {
                decimal d = -999;
                if (decimal.TryParse(s, NumberStyles.Number, CultureInfo.InvariantCulture, out d))
                    return d >= -23 && d <= 23 && d % 0.5M == 0;
                return d != -999;
            }
        }
    }
    

    a different approach is to multiply the result by 10, then use mod 5, to forego the 0.5M requirement.


    My blog: http://blog.jessehouwing.nl/
    • Proposed as answer by Jesse HouwingMVP Wednesday, October 26, 2011 5:23 PM
    • Marked as answer by Paul Zhou Wednesday, November 2, 2011 5:08 AM
    Wednesday, October 26, 2011 5:23 PM
  • @Ron, Actually I did include -23 and +23 and -23.0 and +23.0 using the prefix:

    ^-?(23(\.0)?

    Weird.  I tested without looking too closely at the regex itself and thought it didn't return that.  Sorry.


    Ron
    Wednesday, October 26, 2011 7:31 PM
  • No please don't use double for things that need to be precise. If our case were to accept 10.1, it would break instantly, as .1 cannot correctly be expressed in a double format.
    Yes, you're completely right! I've noticed that the validate method may return true if the string parameter s does not pass the TryParse method because the d will get 0.00... as value and will pass the test d != -999. I've rewritten it in a more logical way.
            static bool Validate(string s)
            {
                decimal d;
                if (decimal.TryParse(s, NumberStyles.Number, CultureInfo.InvariantCulture, out d))
                    return d >= -23 && d <= 23 && (d * 10) % 5M == 0;
                else return false;
            }
    



    aelassas.free.fr
    Wednesday, October 26, 2011 9:57 PM