1.8. Determining Whether a String Is a Valid Number

Problem

You have a string that possibly contains a numeric value. You need to know whether this string contains a valid number.

Solution

Use the static Parse method of any of the numeric types. For example, to determine whether a string contains an integer, use the following method:

public static bool IsNumeric(string str)
{
    try
    {
        str = str.Trim( );
        int foo = int.Parse(str);
        return (true);
    }
    catch (FormatException)
    {
        // Not a numeric value
        return (false);
    }
}

If you instead needed to test whether a string is a floating-point value, change the second line in the try block to the following:

int foo = float.Parse(str);

A more compact way of testing a string for a numeric value—and one that does not have the overhead of throwing an exception—is to use the double.TryParse method:

public static bool IsNumericFromTryParse(string str)
{
    double result = 0;
    return (double.TryParse(str, System.Globalization.NumberStyles.Float, 
            System.Globalization.NumberFormatInfo.CurrentInfo, out result));
}

The following IsNumericRegEx method does not incur the overhead of throwing an exception and it allows more flexibility in determining what type of number to test for. The IsNumericRegEx method tests for a number that can be signed/unsigned, contain a decimal point, and be displayed in scientific notation. This method accepts a string, possibly containing only a number, and returns true or false, depending on whether this string conforms to a numeric value:

private static Regex r = new Regex(@"^[\+\-]?\d*\.?[Ee]?[\+\-]?\d*$", 
                                   RegexOptions.Compiled);

public static bool IsNumericRegEx(string str)
{
    str = str.Trim( );
    Match m = r.Match(str);
    return (m.Value);
}

Discussion

This recipe shows three ways of determining whether a string contains only a numeric value. The IsNumeric method uses the Parse method, which throws a FormatException if the string cannot be converted to the appropriate type. The second method, IsNumericFromTryParse, uses the built-in double.TryParse method; this method also returns a value of type double if the string contains a valid number. The third method, IsNumericRegEx, uses a regular expression to determine whether the value of a string conforms to the various formats of a numeric value, such as an integer, a floating-point value, or a number written in scientific notation.

The method you choose can have a performance impact on your application. It’s not just a question of whether it’s called many times, it’s also about whether a valid number exists within the string passed in to these methods. In some scenarios IsNumeric will be fastest, even if you call it many times. In others, the IsNumericFromTryParse or IsNumericRegEx will be fastest. It all depends on how often the string will not be a valid number. If you expect the string to contain non-numeric data most of the time (or even half the time), you should consider using the IsNumericFromTryParse or IsNumericRegEx methods. Otherwise, the IsNumeric method will give you the best performance.

The IsNumericRegEx method uses the static IsMatch method on the Regex class to attempt to match a numeric value contained in the string str. This static method returns true if the match succeeds and false if it does not. Notice also that the regular expression starts with the ^ character and ends with the $ character. This forces the regular expression to match everything within the string, not just part of the string. If these characters were not included, the IsMatch method would return true for the following string "111 West Ave“.

The IsNumericRegEx method has a drawback: it cannot determine the data type of the number contained within the string. For example, the int.Parse method will accept only strings that contain a valid integer value; likewise, the float.Parse method will accept only strings containing valid float values. The regular expression will return true for any type of numeric value matched. To enhance the regular expression, use the following method to determine whether a value is a non-floating-point number:

public static bool IsIntegerRegEx(string str)
{
    str = str.Trim( );
    return (Regex.IsMatch(str, @"^[\+\-]?\d+$"));
}

We could also use the following method to determine whether the string contains an unsigned number:

public static bool IsUnsignedIntegerRegEx(string str)
{
    str = str.Trim( );
    return (Regex.IsMatch(str, @"^\+?\d+$"));
}

Note also that the Trim method can be excluded if you want to find numbers within strings that contain no beginning or ending whitespace.

Get C# Cookbook now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.