Что такое эквивалент NaN или IsNumeric в C #?


103

Каков наиболее эффективный способ проверки входной строки, содержит ли она числовое значение (или, наоборот, не число)? Думаю, я могу использовать Double.Parseили регулярное выражение (см. Ниже), но мне было интересно, есть ли какой-то встроенный способ сделать это, например, javascript NaN()или IsNumeric()(это был VB, я не могу вспомнить?).

public static bool IsNumeric(this string value)
{
    return Regex.IsMatch(value, "^\\d+$");
}

Ответы:


177

У этого нет накладных расходов на регулярное выражение

double myNum = 0;
String testVar = "Not A Number";

if (Double.TryParse(testVar, out myNum)) {
  // it is a number
} else {
  // it is not a number
}

Между прочим, все стандартные типы данных, за явным исключением GUID, поддерживают TryParse.

update
secretwep сообщил, что значение «2345» пройдет вышеуказанный тест в виде числа. Однако, если вам нужно убедиться, что все символы в строке являются цифрами, следует использовать другой подход.

пример 1 :

public Boolean IsNumber(String s) {
  Boolean value = true;
  foreach(Char c in s.ToCharArray()) {
    value = value && Char.IsDigit(c);
  }

  return value;
}

или если вы хотите быть немного более модным

public Boolean IsNumber(String value) {
  return value.All(Char.IsDigit);
}

обновление 2 (из @stackonfire для работы с нулевыми или пустыми строками)

public Boolean IsNumber(String s) { 
    Boolean value = true; 
    if (s == String.Empty || s == null) { 
        value=false; 
    } else { 
        foreach(Char c in s.ToCharArray()) { 
            value = value && Char.IsDigit(c); 
        } 
    } return value; 
}

При необходимости вы можете обернуть приведенный выше код в более полезный служебный метод, такой как public static bool IsInteger (string sMaybeANumber)
Гишу,

@Gishu: Вы правы, если все, что вас волнует, это то, может ли число преобразовываться.
NotMe

2
Единственная проблема с этим заключается в том, что Numberобъект в Javascript является числом с плавающей точкой или целым числом, поэтому изменение на double. TryParse будет более точным эквивалентом
Крис С.

7
Вы можете быть осторожны с этим, поскольку строки «NaN» и «Infinity» разбираются в a double, но многие сочтут их нечисловыми.
Майк Зборай 01

1
Исправленный пример 1 для работы с нулевыми или пустыми строками, которые в противном случае заставляли IsNumber ошибочно возвращать истину: public Boolean IsNumber(String s) { Boolean value = true; if (s == String.Empty || s == null) { value=false; } else { foreach(Char c in s.ToCharArray()) { value = value && Char.IsDigit(c); } } return value; }
stackonfire

41

Я предпочитаю что-то подобное, это позволяет вам решать, на что NumberStyleтестировать.

public static Boolean IsNumeric(String input, NumberStyles numberStyle) {
    Double temp;
    Boolean result = Double.TryParse(input, numberStyle, CultureInfo.CurrentCulture, out temp);
    return result;
}

7
+1 за то, что он пока единственный человек, использующий Double.TryParse вместо Int.TryParse :)
johnc

Это также, очевидно, почти метод расширения.
Энтони Мастрян,

19

В дополнение к предыдущим правильным ответам, вероятно, стоит указать, что «Not a Number» (NaN) в его общем использовании не эквивалентно строке, которая не может быть оценена как числовое значение. NaN обычно понимается как числовое значение, используемое для представления результата «невозможного» вычисления, когда результат не определен. В этом отношении я бы сказал, что использование Javascript немного вводит в заблуждение. В C # NaN определяется как свойство одинарных и двойных числовых типов и используется для явной ссылки на результат понижения нуля на ноль. В других языках он используется для представления других «невозможных» значений.


11

Я знаю, что на это ответили по-разному, с расширениями и примерами лямбда, но комбинация обоих для простейшего решения.

public static bool IsNumeric(this String s)
{
    return s.All(Char.IsDigit);
}

или если вы используете Visual Studio 2015 (C # 6.0 или выше), тогда

public static bool IsNumeric(this String s) => s.All(Char.IsDigit);

Потрясающий C # 6 в одной строке. Конечно, это ограничено, потому что он проверяет только числовые символы.

Чтобы использовать, просто имейте строку и вызовите на ней метод, например:

bool IsaNumber = "123456".IsNumeric();

1
Для пользователей, незнакомых с методами расширения , может быть полезно включить дополнительную информацию (или, по крайней мере, окружающий статический класс, чтобы предоставить более полный пример).
johnnyRose

Мне не нравится это решение, потому что оно вернет false для чисел с десятичной дробью. Это может быть полезно для целых чисел, но если это то, что вы хотите использовать его для метода должен быть переименован IsInteger
technoman23

5

Да, IsNumeric - это VB. Обычно люди используют метод TryParse (), хотя он немного неуклюжий. Как вы предложили, вы всегда можете написать свой собственный.

int i;
if (int.TryParse(string, out i))
{

}

5

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

    /// <summary>
    /// Extension method that works out if a string is numeric or not
    /// </summary>
    /// <param name="str">string that may be a number</param>
    /// <returns>true if numeric, false if not</returns>
    public static bool IsNumeric(this String str)
    {
        double myNum = 0;
        if (Double.TryParse(str, out myNum))
        {
            return true;
        }
        return false;
    }

4

Вы по-прежнему можете использовать функцию Visual Basic в C #. Единственное, что вам нужно сделать, это просто следовать моим инструкциям, приведенным ниже:

  1. Добавьте ссылку в библиотеку Visual Basic , щелкнув проект правой кнопкой мыши и выбрав «Добавить ссылку »:

введите описание изображения здесь

  1. Затем импортируйте его в свой класс, как показано ниже:

    с использованием Microsoft.VisualBasic;

  2. Затем используйте его, где хотите, как показано ниже:

                if (!Information.IsNumeric(softwareVersion))
            {
                throw new DataException(string.Format("[{0}] is an invalid App Version!  Only numeric values are supported at this time.", softwareVersion));
            }

Надеюсь, что это помогает и удачи!


2
Хотя я бы не рекомендовал этот метод, это правильный ответ. Не уверен, почему за него проголосовали против, и, поскольку тоже не объяснили, почему, я проголосовал за противодействие этому :-)
Abacus

4

VB имеет IsNumericфункцию. Вы можете ссылаться на него Microsoft.VisualBasic.dllи использовать его.


Можно ли получить этот метод VB только в версиях .NET> 2.0?
Эд С.

@ChuckD: Это субъективно. Вы ссылаетесь на внешние библиотеки, которые имеют дело с json, или пишете все это для самостоятельного анализа json?
shahkalpesh

@ChuckD: Избавь меня от чуши и объясни, почему это дерьмо. Для меня это просто еще одна dll, которая содержит несколько полезных классов / функций.
shahkalpesh 05

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

1
@ChuckD, возможно, вы захотите начать с конструктивной критики вместо того, чтобы начинать с импорта VisualBasic.dll для IsNumeric, это должно вас уволить! что явно поможет кому-то вернуться. Ответ был еще в 2009 году и даже сейчас может быть полезен некоторым людям.
Ошибки

4

Простое расширение:

public static bool IsNumeric(this String str)
{
    try
    {
        Double.Parse(str.ToString());
        return true;
    }
    catch {
    }
    return false;
}

если входной параметр - строка, зачем использовать .ToString ()?
technoman23,

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

3
public static bool IsNumeric(string anyString)
{
    if (anyString == null)
    {
        anyString = "";
    }

    if (anyString.Length > 0)
    {
        double dummyOut = new double();
        System.Globalization.CultureInfo cultureInfo = new System.Globalization.CultureInfo("en-US", true);
        return Double.TryParse(anyString, System.Globalization.NumberStyles.Any, cultureInfo.NumberFormat, out dummyOut);
    }
    else
    {
        return false;
    }
}

3

Возможно, это функция C # 3, но вы могли бы ее использовать double.NaN.



2

Я использовал фрагмент Криса Лайвли (выбранный ответ), инкапсулированный в функции bool, такой как предложение Гишу, в течение года или двух. Я использовал его, чтобы убедиться, что определенные строки запроса были только числовыми, прежде чем продолжить дальнейшую обработку. Я начал получать некоторые ошибочные строки запроса, которые не обрабатывались отмеченным ответом, в частности, всякий раз, когда после числа вроде «3645» ставилась запятая (возвращалось истина). Это получившийся мод:

   static public bool IsNumeric(string s)
   {
      double myNum = 0;
      if (Double.TryParse(s, out myNum))
      {
         if (s.Contains(",")) return false;
         return true;
      }
      else
      {
         return false;
      }
   }

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

Double.TryParse(s, NumberStyles.Float, CultureInfo.InvariantCulture, out myNum)
Sam Harwell

0

У меня немного другая версия, которая возвращает число. Я предполагаю, что в большинстве случаев после тестирования строки вы захотите использовать номер.

public bool IsNumeric(string numericString, out Double numericValue)
{
    if (Double.TryParse(numericString, out numericValue))
        return true;
    else
        return false;
}

0

Это модифицированная версия решения, предложенного г-ном Сииром. Я считаю, что добавление метода расширения - лучшее решение для повторного использования и простоты вызывающего метода.

public static bool IsNumeric(this String s)
{
    try { double.Parse(s); return true; }
    catch (Exception) { return false; }
}

Я изменил тело метода, чтобы он умещался в 2 строки, и удалил ненужную реализацию .ToString (). Для тех, кто не знаком с методами расширения, вот как реализовать:

Создайте файл класса ExtensionMethods . Вставьте этот код:

using System;
using System.Collections.Generic;
using System.Text;

namespace YourNameSpaceHere
{
    public static class ExtensionMethods
    {
        public static bool IsNumeric(this String s)
        {
            try { double.Parse(s); return true; }
            catch (Exception) { return false; }
        }
    }
}

Замените YourNameSpaceHere своим фактическим NameSpace. Сохранить изменения. Теперь вы можете использовать метод расширения в любом месте вашего приложения:

bool validInput = stringVariable.IsNumeric();

Примечание: этот метод вернет true для целых и десятичных чисел, но вернет false, если строка содержит запятую. Если вы хотите принимать ввод с запятыми или символами, такими как «$», я бы предложил реализовать метод для удаления этих символов сначала, а затем проверить, является ли IsNumeric.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.