Recipe 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.
|