tags:

views:

329

answers:

5

I have written regexes for recognizing float and int but they don't seem to work (code below).

{
    string sumstring = "12.098";

    Regex flt = new Regex(@" ^[0-9]*(\.[0-9]*)");
    Regex ent = new Regex("^[0-9]+");

    if (d_type.IsMatch(sumstring))
    {
        Console.WriteLine(sumstring + " " + "dtype");
    }

    Match m = ent.Match(sumstring);

    if (m.Success)
    {
        Console.WriteLine("int");
    }
    else if (flt.IsMatch(sumstring))
    {
        Console.WriteLine("float");
    }
}

Where is the mistake?

+1  A: 

You're trying your tests in the wrong order -- switch them, or (*) put a $ at the end of your RE patterns, to ensure they match all the way to the end.

(*) depends on what you're trying to do, exactly: match strings that start with the representation of an integer or float, or, only strings that are entirely composed of such a representation?

Alex Martelli
thank you very much
intrinsic
+1  A: 

the "ent" regex should be anchored: Regex ent = new Regex("^[0-9]+$");

You were matching just the first numbers ...

Hans Kesting
thank you very much
intrinsic
A: 

the regex should have to match the entire string. "^\d*\.\d*$" would match. Alternatively you can just search for a period in the string.

Ben Hughes
thank you very much
intrinsic
+10  A: 

First, I don't think regular expressions are really the best tool for this job. I would simply use the Double.TryParse() and Int32.TryParse() functions.

Second, you're missing a whole lot of test cases with your regular expressions:

  • Integer
    • 5 (covered)
    • +5 (not covered)
    • -5 (not covered)
  • Double
    • 5.0 (covered)
    • +5.0 (not covered)
    • -5.0 (not covered)
    • 5.0E5 (not covered)
    • 5.0E+5 (not covered)
    • 5.0E-5 (not covered)
    • +5.0E5 (not covered)
    • +5.0E+5 (not covered)
    • +5.0E-5 (not covered)
    • -5.0E5 (not covered)
    • -5.0E+5 (not covered)
    • -5.0E-5 (not covered)
  • Edge Cases
    • 2^32 + 1 (should be recognized as Double even though it looks like Integer)

All of these (except maybe the edge case) would be immediately covered by using the library instead of hand-rolling a regex.

Lee
I agree. Don't reinvent the wheel, and the performance of your RegEx will be far slower than using the TryParse
chris.w.mclean
thanku for correcting me.
intrinsic
+1  A: 

I don't know how compatible C#'s regular expressions are with Perl's, but I try not to reinvent the wheel unless it need reinventing:

% perl -e 'use Regexp::Common; print $RE{num}{real}, "\n"'
(?:(?i)(?:[+-]?)(?:(?=[0123456789]|[.])(?:[0123456789]*)(?:(?:[.])(?:[0123456789]{0,}))?)(?:(?:[E])(?:(?:[+-]?)(?:[0123456789]+))|))

Now, I don't get why they didn't use [0-9], but this works well.

xcramps
thanku so much..u guys really helped alot
intrinsic