Identify if a string is a number

前端 未结 25 3053
無奈伤痛
無奈伤痛 2020-11-22 00:13

If I have these strings:

  1. \"abc\" = false

  2. \"123\" = true

  3. \"ab2\"

相关标签:
25条回答
  • 2020-11-22 00:31

    This is probably the best option in C#.

    If you want to know if the string contains a whole number (integer):

    string someString;
    // ...
    int myInt;
    bool isNumerical = int.TryParse(someString, out myInt);
    

    The TryParse method will try to convert the string to a number (integer) and if it succeeds it will return true and place the corresponding number in myInt. If it can't, it returns false.

    Solutions using the int.Parse(someString) alternative shown in other responses works, but it is much slower because throwing exceptions is very expensive. TryParse(...) was added to the C# language in version 2, and until then you didn't have a choice. Now you do: you should therefore avoid the Parse() alternative.

    If you want to accept decimal numbers, the decimal class also has a .TryParse(...) method. Replace int with decimal in the above discussion, and the same principles apply.

    0 讨论(0)
  • 2020-11-22 00:33

    I guess this answer will just be lost in between all the other ones, but anyway, here goes.

    I ended up on this question via Google because I wanted to check if a string was numeric so that I could just use double.Parse("123") instead of the TryParse() method.

    Why? Because it's annoying to have to declare an out variable and check the result of TryParse() before you know if the parse failed or not. I want to use the ternary operator to check if the string is numerical and then just parse it in the first ternary expression or provide a default value in the second ternary expression.

    Like this:

    var doubleValue = IsNumeric(numberAsString) ? double.Parse(numberAsString) : 0;
    

    It's just a lot cleaner than:

    var doubleValue = 0;
    if (double.TryParse(numberAsString, out doubleValue)) {
        //whatever you want to do with doubleValue
    }
    

    I made a couple extension methods for these cases:


    Extension method one

    public static bool IsParseableAs<TInput>(this string value) {
        var type = typeof(TInput);
    
        var tryParseMethod = type.GetMethod("TryParse", BindingFlags.Static | BindingFlags.Public, Type.DefaultBinder,
            new[] { typeof(string), type.MakeByRefType() }, null);
        if (tryParseMethod == null) return false;
    
        var arguments = new[] { value, Activator.CreateInstance(type) };
        return (bool) tryParseMethod.Invoke(null, arguments);
    }
    

    Example:

    "123".IsParseableAs<double>() ? double.Parse(sNumber) : 0;
    

    Because IsParseableAs() tries to parse the string as the appropriate type instead of just checking if the string is "numeric" it should be pretty safe. And you can even use it for non numeric types that have a TryParse() method, like DateTime.

    The method uses reflection and you end up calling the TryParse() method twice which, of course, isn't as efficient, but not everything has to be fully optimized, sometimes convenience is just more important.

    This method can also be used to easily parse a list of numeric strings into a list of double or some other type with a default value without having to catch any exceptions:

    var sNumbers = new[] {"10", "20", "30"};
    var dValues = sNumbers.Select(s => s.IsParseableAs<double>() ? double.Parse(s) : 0);
    

    Extension method two

    public static TOutput ParseAs<TOutput>(this string value, TOutput defaultValue) {
        var type = typeof(TOutput);
    
        var tryParseMethod = type.GetMethod("TryParse", BindingFlags.Static | BindingFlags.Public, Type.DefaultBinder,
            new[] { typeof(string), type.MakeByRefType() }, null);
        if (tryParseMethod == null) return defaultValue;
    
        var arguments = new object[] { value, null };
        return ((bool) tryParseMethod.Invoke(null, arguments)) ? (TOutput) arguments[1] : defaultValue;
    }
    

    This extension method lets you parse a string as any type that has a TryParse() method and it also lets you specify a default value to return if the conversion fails.

    This is better than using the ternary operator with the extension method above as it only does the conversion once. It still uses reflection though...

    Examples:

    "123".ParseAs<int>(10);
    "abc".ParseAs<int>(25);
    "123,78".ParseAs<double>(10);
    "abc".ParseAs<double>(107.4);
    "2014-10-28".ParseAs<DateTime>(DateTime.MinValue);
    "monday".ParseAs<DateTime>(DateTime.MinValue);
    

    Outputs:

    123
    25
    123,78
    107,4
    28.10.2014 00:00:00
    01.01.0001 00:00:00
    
    0 讨论(0)
  • 2020-11-22 00:33

    Use these extension methods to clearly distinguish between a check if the string is numerical and if the string only contains 0-9 digits

    public static class ExtensionMethods
    {
        /// <summary>
        /// Returns true if string could represent a valid number, including decimals and local culture symbols
        /// </summary>
        public static bool IsNumeric(this string s)
        {
            decimal d;
            return decimal.TryParse(s, System.Globalization.NumberStyles.Any, System.Globalization.CultureInfo.CurrentCulture, out d);
        }
    
        /// <summary>
        /// Returns true only if string is wholy comprised of numerical digits
        /// </summary>
        public static bool IsNumbersOnly(this string s)
        {
            if (s == null || s == string.Empty)
                return false;
    
            foreach (char c in s)
            {
                if (c < '0' || c > '9') // Avoid using .IsDigit or .IsNumeric as they will return true for other characters
                    return false;
            }
    
            return true;
        }
    }
    
    0 讨论(0)
  • 2020-11-22 00:33

    All the Answers are Useful. But while searching for a solution where the Numeric value is 12 digits or more (in my case), then while debugging, I found the following solution useful :

    double tempInt = 0;
    bool result = double.TryParse("Your_12_Digit_Or_more_StringValue", out tempInt);
    

    Th result variable will give you true or false.

    0 讨论(0)
  • 2020-11-22 00:34
    int n;
    bool isNumeric = int.TryParse("123", out n);
    

    Update As of C# 7:

    var isNumeric = int.TryParse("123", out int n);
    

    or if you don't need the number you can discard the out parameter

    var isNumeric = int.TryParse("123", out _);
    

    The var s can be replaced by their respective types!

    0 讨论(0)
  • 2020-11-22 00:34

    If you want to know if a string is a number, you could always try parsing it:

    var numberString = "123";
    int number;
    
    int.TryParse(numberString , out number);
    

    Note that TryParse returns a bool, which you can use to check if your parsing succeeded.

    0 讨论(0)
提交回复
热议问题