Как определить, является ли строка числом?

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

  1. "abc" = false

  2. "123" = true

  3. "ab2" = false

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

21 ответов


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

обновление начиная с C# 7:

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

на var s могут быть заменены их соответствующими типами!


это вернет true, если input все цифры. Не знаю, лучше ли это, чем TryParse, но это сработает.

Regex.IsMatch(input, @"^\d+$")

если вы просто хотите знать, имеет ли он одно или несколько чисел, смешанных с символами, оставьте ^ + и $.

Regex.IsMatch(input, @"\d")

Edit: На самом деле я думаю, что это лучше, чем TryParse, потому что очень длинная строка потенциально может переполнить TryParse.


вы также можете использовать:

stringTest.All(char.IsDigit);

вернет true для всех цифр (не float) и false если строка ввода какой-либо цифры.

обратите внимание: stringTest не должно быть пустой строкой, так как это пройдет тест на числовое значение.


я использовал эту функцию несколько раз:

public static bool IsNumeric(object Expression)
{
    double retNum;

    bool isNum = Double.TryParse(Convert.ToString(Expression), System.Globalization.NumberStyles.Any, System.Globalization.NumberFormatInfo.InvariantInfo, out retNum);
    return isNum;
}

но вы также можете использовать;

bool b1 = Microsoft.VisualBasic.Information.IsNumeric("1"); //true
bool b2 = Microsoft.VisualBasic.Information.IsNumeric("1aa"); // false

С Бенчмаркинг IsNumeric Options

alt текст http://aspalliance.com/images/articleimages/80/Figure1.gif

alt текст http://aspalliance.com/images/articleimages/80/Figure2.gif


это, вероятно, лучший вариант в C#.

если вы хотите знать, если строка содержит целое число (целое число):

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

метод TryParse попытается преобразовать строку в число (целое число), и если это удастся, он вернет true и разместит соответствующее число в myInt. Если он не может, он возвращает false.

решениями int.Parse(someString) альтернатива, показанная в других ответах, работает, но она намного медленнее, потому что исключение очень дорогой. TryParse(...) был добавлен в язык C# в версии 2, а до тех пор у вас не было выбора. Теперь вы делаете: поэтому вы должны избегать Parse() альтернативы.

если вы хотите принять десятичные числа, десятичный класс также имеет .TryParse(...) метод. Замените int на decimal в приведенном выше обсуждении, и применяются те же принципы.


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

пример.

decimal myDec;
var Result = decimal.TryParse("123", out myDec);

результат будет тогда = True

decimal myDec;
var Result = decimal.TryParse("abc", out myDec);

результат будет тогда = False


в случае, если вы не хотите использовать int.Разбор или удвоение.Разбор, вы можете свернуть свой собственный с чем-то вроде этого:

public static class Extensions
{
    public static bool IsNumeric(this string s)
    {
        foreach (char c in s)
        {
            if (!char.IsDigit(c) && c != '.')
            {
                return false;
            }
        }

        return true;
    }
}

Я знаю, что это старый поток, но ни один из ответов на самом деле не сделал это для меня - либо неэффективно, либо не инкапсулировано для легкого повторного использования. Я также хотел убедиться, что он возвращает false, если строка пустая или null. TryParse возвращает true в этом случае (пустая строка не вызывает ошибки при синтаксическом анализе в виде числа). Итак, вот мой метод расширения строки:

public static class Extensions
{
    /// <summary>
    /// Returns true if string is numeric and not empty or null or whitespace.
    /// Determines if string is numeric by parsing as Double
    /// </summary>
    /// <param name="str"></param>
    /// <param name="style">Optional style - defaults to NumberStyles.Number (leading and trailing whitespace, leading and trailing sign, decimal point and thousands separator) </param>
    /// <param name="culture">Optional CultureInfo - defaults to InvariantCulture</param>
    /// <returns></returns>
    public static bool IsNumeric(this string str, NumberStyles style = NumberStyles.Number,
        CultureInfo culture = null)
    {
        double num;
        if (culture == null) culture = CultureInfo.InvariantCulture;
        return Double.TryParse(str, style, culture, out num) && !String.IsNullOrWhiteSpace(str);
    }
}

прост в использовании:

var mystring = "1234.56789";
var test = mystring.IsNumeric();

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

var mystring = "5.2453232E6";
var test = mystring.IsNumeric(style: NumberStyles.AllowExponent);

или для проверки потенциальной шестнадцатеричной строки вы можете использовать:

var mystring = "0xF67AB2";
var test = mystring.IsNumeric(style: NumberStyles.HexNumber)

необязательный параметр "culture" можно использовать почти таким же образом.

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


Если вы хотите поймать более широкий спектр чисел, à la PHP is_numeric, вы можете использовать следующее:

// From PHP documentation for is_numeric
// (http://php.net/manual/en/function.is-numeric.php)

// Finds whether the given variable is numeric.

// Numeric strings consist of optional sign, any number of digits, optional decimal part and optional
// exponential part. Thus +0123.45e6 is a valid numeric value.

// Hexadecimal (e.g. 0xf4c3b00c), Binary (e.g. 0b10100111001), Octal (e.g. 0777) notation is allowed too but
// only without sign, decimal and exponential part.
static readonly Regex _isNumericRegex =
    new Regex(  "^(" +
                /*Hex*/ @"0x[0-9a-f]+"  + "|" +
                /*Bin*/ @"0b[01]+"      + "|" + 
                /*Oct*/ @"0[0-7]*"      + "|" +
                /*Dec*/ @"((?!0)|[-+]|(?=0+\.))(\d*\.)?\d+(e\d+)?" + 
                ")$" );
static bool IsNumeric( string value )
{
    return _isNumericRegex.IsMatch( value );
}

Единица Тест:

static void IsNumericTest()
{
    string[] l_unitTests = new string[] { 
        "123",      /* TRUE */
        "abc",      /* FALSE */
        "12.3",     /* TRUE */
        "+12.3",    /* TRUE */
        "-12.3",    /* TRUE */
        "1.23e2",   /* TRUE */
        "-1e23",    /* TRUE */
        "1.2ef",    /* FALSE */
        "0x0",      /* TRUE */
        "0xfff",    /* TRUE */
        "0xf1f",    /* TRUE */
        "0xf1g",    /* FALSE */
        "0123",     /* TRUE */
        "0999",     /* FALSE (not octal) */
        "+0999",    /* TRUE (forced decimal) */
        "0b0101",   /* TRUE */
        "0b0102"    /* FALSE */
    };

    foreach ( string l_unitTest in l_unitTests )
        Console.WriteLine( l_unitTest + " => " + IsNumeric( l_unitTest ).ToString() );

    Console.ReadKey( true );
}

имейте в виду, что только потому, что это числовое значение, не означает, что его можно преобразовать в числовой тип. Например, "999999999999999999999999999999.9999999999" является совершенным допустимым числовым значением, но оно не будет вписываться в числовой тип .NET (не определенный в стандартной библиотеке).


если вы хотите проверить, является ли строка числом (я предполагаю, что это строка, так как если это число, вы знаете, что это один).

  • без regex и
  • используя код Microsoft как можно больше

вы также можете сделать:

public static bool IsNumber(this string aNumber)
{
     BigInteger temp_big_int;
     var is_number = BigInteger.TryParse(aNumber, out temp_big_int);
     return is_number;
}

об этом позаботятся обычные гадости:

  • минус (-) или плюс (+) в начале
  • содержится десятичный символ BigIntegers не разбор чисел с десятичными точками. (Итак:BigInteger.Parse("3.3") выдаст исключение, и TryParse для того же вернет false)
  • нет смешных без цифр
  • распространяется на случаи, когда число больше, чем обычное использование Double.TryParse

вы должны добавить ссылку System.Numerics и using System.Numerics; на вершине вашего класса (ну, второй бонус, я думаю :)


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

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

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


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

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

почему? Потому что это раздражает, чтобы объявить out переменная и проверьте результат TryParse() перед вами сейчас, если разбор не удался или нет. Я хочу использовать ternary operator чтобы проверить, если string is 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

двойной.Метод tryparse

bool Double.TryParse(string s, out double result)

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

var numberString = "123";
int number;

int.TryParse(numberString , out number);

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


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

if(int.TryParse(str, out int v))
{
}

используйте эти методы расширения, чтобы четко различать проверку, если строка численное и если строка только содержит 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;
    }
}

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

надеюсь, что это помогает

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

if isNumber 
{
//string is number
}
else
{
//string is not a number
}


извлеките ссылку на Visual Basic в проекте и используйте ее сведения.IsNumeric метод, такой как показано ниже, и быть в состоянии захватить поплавки, а также целые числа в отличие от ответа выше, который только ловит ints.

    // Using Microsoft.VisualBasic;

    var txt = "ABCDEFG";

    if (Information.IsNumeric(txt))
        Console.WriteLine ("Numeric");

IsNumeric("12.3"); // true
IsNumeric("1"); // true
IsNumeric("abc"); // false

//To my knowledge I did this in a simple way
static void Main(string[] args)
{
    string a, b;
    int f1, f2, x, y;
    Console.WriteLine("Enter two inputs");
    a = Convert.ToString(Console.ReadLine());
    b = Console.ReadLine();
    f1 = find(a);
    f2 = find(b);

    if (f1 == 0 && f2 == 0)
    {
        x = Convert.ToInt32(a);
        y = Convert.ToInt32(b);
        Console.WriteLine("Two inputs r number \n so that addition of these text box is= " + (x + y).ToString());
    }
    else
        Console.WriteLine("One or two inputs r string \n so that concatenation of these text box is = " + (a + b));
    Console.ReadKey();
}

static int find(string s)
{
    string s1 = "";
    int f;
    for (int i = 0; i < s.Length; i++)
       for (int j = 0; j <= 9; j++)
       {
           string c = j.ToString();
           if (c[0] == s[i])
           {
               s1 += c[0];
           }
       }

    if (s == s1)
        f = 0;
    else
        f = 1;

    return f;
}