Что такое эквивалент 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.