In this article, we are going to learn some different ways to identify if a string is a number in C# and compare them with a benchmark to determine the fastest and the slowest approach.
With that, let’s start.
Use TryParse() Method To Identify If a String is a Number
Before we start coding, let’s create a console application using the Visual Studio wizard or the dotnet new console
command.
The simplest way to identify if a string is a number in C# is by using the int.TryParse()
method against the string:
int.TryParse(stringValue, out _);
This method receives a string value as a parameter and tries to parse it into an int. In case the parse was successful, it returns true, otherwise false.
Note that, the TryParse()
method has a second argument. That is an out argument that means that if the parse is successful, the TryParse()
method will assign the parsed value to this argument. In this case, we use the discard key (_
) to indicate that we don’t need this value.
Let’s run this method against an array of string values:
var values = new string[] { "1234","ABC-789", "1.23", "9999999999" };
The first value represents an integer number which our method must parse as a number. The second value is an alphanumeric string, so we expect the int.TryParse()
method to return false.
Now, let’s analyze the result:
"1234" // true "ABC-789" // false "1.23" // false "9999999999" // false
As we can see, the values 1.23
and 9999999999
are numbers, but they evaluate as false. That happens because we are using the int.TryParse()
method which checks only for the int data type.
Note that 9999999999
is, mathematically, an integer number. However, it isn’t an int
because it exceeds the maximum value of the int
(Int32
) data type, which is 2,147,483,647
. Thus, the int.TryParse()
method evaluates it as false. Â
It is worth noting that, besides int.TryParse()
, we can use this method for every value type, which includes: int
, long
, double
, float
, bool
and others.
That said, let’s switch the int.TryParse()
to double.TryParse()
to validate if a string is a valid number:
double.TryParse(stringValue, out _);
Now, let’s run the method against the same array of strings:
"1234" // true "ABC-789" // false "1.23" // true "9999999999" // true
Now, the values 1.23
and 9999999999
both evaluate as true. That’s because the double datatype handles both mathematical integers and non-integer numeric values.
Use Regex to Identify If a String is a Number
Regular expressions can be extremely helpful when checking patterns within a string.
We will use this tool to check whether a given string represents a number or not:
public static bool UsingRegex(string stringValue) { var pattern = @"^-?\d+(?:\.\d+)?$";Â var regex = new Regex(pattern); return regex.IsMatch(stringValue); }
Here, we have a method that receives a string (stringValue
) as input and returns true
if this input represents a number, and false
otherwise.
To perform this validation, we create a simple regular expression pattern (^-?\d+(?:\.\d+)?$
). First, this pattern checks if the string starts with an optional minus sign (-?
) indicating a negative value.
The second step consists of validating if the string has one or more digits (\d+
).
Finally, the regular expression checks if the string has an optional decimal point followed by one or more digits (?:\.\d+)?$
).
Now that our pattern is ready, we instantiate a new regex
object that takes this pattern as a parameter. Next, we use the IsMatch()
method to validate the string by passing it as an argument and returning the result.
In this case, we separate decimals point with a dot (.
), however, if we want to use commas (,
), we could simply modify the regex pattern expression to adapt to this change.
Also, if we want to validate only integers numbers, we can modify the regular expression to ^-?\d+$
.Â
Use Char.IsDigit and All() Method
In this approach, we are going to use the All()
extension method to check if every character in the string is a number.
Let’s check this approach:
public static bool UsingCharIsDigit(string stringValue) { return stringValue.All(char.IsDigit); }
Here, we use the All()
extension method that is responsible to iterate over each character in the input string and verify if it represents a number. If every character is a number, we return true, otherwise false.
Note that, as with the int.TryParse()
method, this approach works for integer numbers as well. However, different from the int.TryParse()
method, this approach can validate numbers that exceed the int
data type max value.
What Is the Fastest Way to Verify if a String Is a Number?
After learning the different ways to verify if a string is a number, let’s analyze a benchmark result to determine which is the fastest way to check if a string is a number:
| Method | Mean | Error | StdDev | Median | |----------------- |------------:|----------:|-----------:|------------:| | IntTryParse | 30.22 ns | 0.633 ns | 1.646 ns | 30.14 ns | | UsingCharIsDigit | 114.69 ns | 1.139 ns | 1.010 ns | 114.37 ns | | DoubleTryParse | 125.21 ns | 2.573 ns | 6.733 ns | 126.00 ns | | UsingRegex | 3,720.16 ns | 76.942 ns | 221.994 ns | 3,609.80 ns |
As we can see in this benchmark result, the UsingRegex
approach is significantly slower than the IntTryParse
approach. Despite its slower performance, the regex approach is more flexible, and it allows us to validate integers and non-integer values.
Although we don’t have much flexibility when we are using the DoubleTryParse
approach, it performs this job with decimal points, achieving almost 30 times faster than when we are using Regex.
When we use the CharIsDigit
approach, we have the second-best result, but we can use this approach only if we deal with mathematical integer numbers.
It’s worth mentioning that we can combine multiple approaches to achieve the same result. For example, if we require high performance, we can combine the IntTryParse
and DoubleTryParse
approaches to handle integer and non-integer values. These two approaches combined are still more efficient than using Regex
.
Conclusion
In this article, we have learned four different ways to verify if a string can parse in a number.
We have seen the limitations of the Int.TryParse() and Char.IsDigit approach as well as the flexibility that using regex gives us when we need to change the way we verify the string, however, it’s less efficient than all other approaches we have discussed.
We have also seen that the DoubleTryParse approach, besides being efficient, can parse large numbers with or without decimal points.
Anyway, it is up to us to decide which one fits better to our algorithm and use case.