Определите, является ли строка числом - PullRequest
649 голосов
/ 21 мая 2009

Если у меня есть эти строки:

  1. "abc" = false

  2. "123" = true

  3. "ab2" = false

Есть ли команда, например IsNumeric() или что-то еще, которая может определить, является ли строка допустимым числом?

Ответы [ 23 ]

9 голосов
/ 21 мая 2009

Вы можете использовать TryParse, чтобы определить, может ли строка быть проанализирована в целое число.

int i;
bool bNum = int.TryParse(str, out i);

Логическое значение скажет вам, работает ли оно или нет.

8 голосов
/ 07 марта 2014

Полагаю, этот ответ будет просто потерян между всеми остальными, но в любом случае, вот так.

Я попал на этот вопрос через Google, потому что хотел проверить, было ли string numeric, чтобы я мог просто использовать double.Parse("123") вместо TryParse() метода.

Почему? Потому что раздражает необходимость объявлять переменную out и проверять результат TryParse(), прежде чем вы узнаете, был ли сбой анализа или нет. Я хочу использовать ternary operator, чтобы проверить, является ли string numerical, а затем просто проанализировать его в первом троичном выражении или указать значение по умолчанию во втором троичном выражении.

Как это:

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

Это намного чище, чем:

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

Я сделал пару extension methods для этих случаев:


Метод расширения один

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);
}

Пример:

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

Поскольку IsParseableAs() пытается проанализировать строку как соответствующий тип вместо того, чтобы просто проверять, является ли строка "числовой", она должна быть довольно безопасной. И вы даже можете использовать его для нечисловых типов, которые имеют метод TryParse(), например DateTime.

Метод использует рефлексию, и в итоге вы вызываете метод TryParse() дважды, что, конечно, не так эффективно, но не все должно быть полностью оптимизировано, иногда удобство просто важнее.

Этот метод также можно использовать для простого разбора списка числовых строк в список double или некоторого другого типа со значением по умолчанию без необходимости перехвата каких-либо исключений:

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

Метод расширения два

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;
}

Этот метод расширения позволяет вам анализировать string как любой type, у которого есть метод TryParse(), и также позволяет указать значение по умолчанию, которое будет возвращаться в случае сбоя преобразования.

Это лучше, чем использовать троичный оператор с методом расширения, описанным выше, поскольку он выполняет преобразование только один раз. Это все еще использует отражение, хотя ...

Примеры:

"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);

Выходы:

123
25
123,78
107,4
28.10.2014 00:00:00
01.01.0001 00:00:00
6 голосов
/ 21 мая 2009

Если вы хотите узнать, является ли строка числом, вы всегда можете попробовать ее проанализировать:

var numberString = "123";
int number;

int.TryParse(numberString , out number);

Обратите внимание, что TryParse возвращает bool, который можно использовать для проверки успешности анализа.

6 голосов
/ 21 мая 2009

Double.TryParse

bool Double.TryParse(string s, out double result)
3 голосов
/ 18 октября 2018

ОБНОВЛЕНИЕ Кунала Ноэля Ответ

stringTest.All(char.IsDigit);
// This returns true if all characters of the string are digits.

Но для этого случая у нас есть пустые строки, которые пройдут этот тест, поэтому вы можете:

if (!string.IsNullOrEmpty(stringTest) && stringTest.All(char.IsDigit)){
   // Do your logic here
}
2 голосов
/ 31 июля 2018
public static bool IsNumeric(this string input)
{
    int n;
    if (!string.IsNullOrEmpty(input)) //.Replace('.',null).Replace(',',null)
    {
        foreach (var i in input)
        {
            if (!int.TryParse(i.ToString(), out n))
            {
                return false;
            }

        }
        return true;
    }
    return false;
}
2 голосов
/ 03 июля 2018

Используйте эти методы расширения, чтобы четко различать проверку, является ли строка числовой и если строка только содержит 0-9 цифр

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;
    }
}
2 голосов
/ 10 ноября 2017

С помощью c # 7 вы можете встроить переменную out:

if(int.TryParse(str, out int v))
{
}
1 голос
/ 02 января 2013

Надеюсь, это поможет

string myString = "abc";
double num;
bool isNumber = double.TryParse(myString , out num);

if isNumber 
{
//string is number
}
else
{
//string is not a number
}
1 голос
/ 08 декабря 2018

Лучшее гибкое решение со встроенной функцией .net под названием- char.IsDigit. Работает с неограниченными длинными номерами. Он вернет true, только если каждый символ представляет собой числовое число. Я использовал его много раз без проблем и с гораздо более простым решением, которое я когда-либо нашел. Я сделал пример метода. Он готов к использованию. Кроме того, я добавил валидацию для нулевого и пустого ввода. Таким образом, метод теперь полностью пуленепробиваемый

public static bool IsNumeric(string strNumber)
    {
        if (string.IsNullOrEmpty(strNumber))
        {
            return false;
        }
        else
        {
            int numberOfChar = strNumber.Count();
            if (numberOfChar > 0)
            {
                bool r = strNumber.All(char.IsDigit);
                return r;
            }
            else
            {
                return false;
            }
        }
    }
...