Каков наиболее эффективный способ проверки входной строки, содержит ли она числовое значение (или, наоборот, не число)? Думаю, я могу использовать Double.Parse или регулярное выражение (см. Ниже), но мне было интересно, есть ли какие-то встроенные способы сделать это, например NaN() или IsNumeric() в javascript (это был VB, я не могу вспомнить?).
public static bool IsNumeric(this string value)
{
return Regex.IsMatch(value, "^\\d+$");
}





У этого нет накладных расходов на регулярное выражение
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.
Обновить
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: Вы правы, если все, что вас волнует, это то, может ли число конвертироваться.
Единственная проблема заключается в том, что объект Number в Javascript является числом с плавающей запятой или целым числом, поэтому изменение на double.TryParse будет более точным эквивалентом.
Вы можете быть осторожны с этим, поскольку строки «NaN» и «Infinity» анализируются до double, но многие сочтут их нечисловыми.
Пример 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: ваше обновление выглядит неплохо, я включил его в пост.
VB имеет функцию IsNumeric. Вы можете сослаться на Microsoft.VisualBasic.dll и использовать его.
Можно ли получить этот метод VB только в версиях .NET> 2.0?
@ChuckD: Это субъективно. Вы ссылаетесь на внешние библиотеки, которые имеют дело с json, или пишете все для самостоятельного анализа json?
@ChuckD: Избавь меня от чуши и объясни, почему это дерьмо. Для меня это просто еще одна dll, которая содержит несколько полезных классов / функций.
@ChuckD Я думаю, что ты здесь неразумен. Функция выполняет свою работу, ее легко импортировать, и это не так уж и важно.
@JoelCoehoorn: Считаете ли вы, что использовать microsoft.visualbasic.dll и использовать некоторые из предоставленных в нем функций - плохая идея, независимо от того, можно ли использовать эквивалентную функцию из C# без ссылки на другую dll?
Is numeric - это однострочное расширение для записи на C#. Зачем вам тащить раздутую устаревшую dll, которая, как я предполагаю, также включает в себя множество ссылок на взаимодействие с COM и дополнительные накладные расходы. Вы включаете такие вещи, как Json.Net, потому что они целенаправленны и не влекут за собой дополнительных зависимостей. Попробуйте перетащить VisualBasic.dll и перенесите свои файлы в Mono. Никто не должен учить вас этим вредным привычкам.
@ChuckD: Вы расширяете его до Mono, вопрос не в этом. Если бы это был Mono, все было бы иначе. Как Visualbasic.dll унаследовал / раздулся? Как вызов Isnumeric включает в себя com-взаимодействие?
@ChuckD: Я не знаю, почему ребята из MS пишут чушь (?) Вроде это
@shahkalpesh - Здесь не место для обсуждения здравого смысла. Пожалуйста, продолжайте кодировать так, как вы считаете логичным, и я буду продолжать делать то же самое. Если вы посмотрите на направление .Net Core, вы поймете мои проблемы. Кроме того, взгляните на широко распространенный ответ и примите несколько советов, вместо того чтобы подвергать сомнению чей-то отзыв.
@ChuckD, возможно, вы захотите начать с конструктивной критики вместо того, чтобы начинать с Импорт VisualBasic.dll для IsNumeric должен вас уволить!, что явно поможет кому-то вернуться. Ответ был еще в 2009 году и даже сейчас может быть полезен некоторым людям.
Мои извинения, комментарии были убраны. Если вы решили аргументировать свой предложенный ответ вместо принятого, значит, вы неправильно используете сайт.
Да, IsNumeric - это VB. Обычно люди используют метод TryParse (), хотя он немного неуклюжий. Как вы предложили, вы всегда можете написать свой собственный.
int i;
if (int.TryParse(string, out i))
{
}
Я предпочитаю что-то вроде этого, это позволяет вам решать, на что тестировать NumberStyle.
public static Boolean IsNumeric(String input, NumberStyles numberStyle) {
Double temp;
Boolean result = Double.TryParse(input, numberStyle, CultureInfo.CurrentCulture, out temp);
return result;
}
+1 за то, что пока что был единственным человеком, использующим Double.TryParse вместо Int.TryParse :)
Это тоже, очевидно, почти метод расширения.
В дополнение к предыдущим правильным ответам, вероятно, стоит указать, что «Not a Number» (NaN) в его общем использовании является эквивалентом нет строки, которая не может быть оценена как числовое значение. NaN обычно понимается как числовое значение, используемое для представления результата «невозможного» вычисления, когда результат не определен. В этом отношении я бы сказал, что использование Javascript немного вводит в заблуждение. В C# NaN определяется как свойство одинарных и двойных числовых типов и используется для явной ссылки на результат понижения нуля на ноль. В других языках он используется для представления других «невозможных» значений.
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;
}
}
Возможно, это функция C# 3, но вы могли бы использовать double.NaN.
Фактически, Double.NaN поддерживается во всех версиях .NET 2.0 и выше.
Простое расширение:
public static bool IsNumeric(this String str)
{
try
{
Double.Parse(str.ToString());
return true;
}
catch {
}
return false;
}
если входной параметр - строка, зачем использовать .ToString ()?
Этот ответ хорош, поскольку он устраняет ненужную переменную, необходимую для метода TryParse, который используется в ответах, таких как решение NER1808.
Я использовал фрагмент Криса Лайвли (выбранный ответ), инкапсулированный в функции 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 за то, что интересно. Думаю, это скорее вопрос использования. Другими словами, если вы просто хотите убедиться, что значение можно преобразовать в число без выдачи ошибки, тогда мой исходный ответ хорош. Однако, если вас больше беспокоит, что все символы в строке на самом деле являются цифрами, необходим совершенно другой подход.
Double.TryParse(s, NumberStyles.Float, CultureInfo.InvariantCulture, out myNum)Мне нравится метод расширения, но я не люблю генерировать исключения, если это возможно. Я выбрал метод расширения, использующий здесь лучший из двух ответов.
/// <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;
}
Вы по-прежнему можете использовать функцию Visual Basic в C#. Единственное, что вам нужно сделать, это просто следовать моим инструкциям, показанным ниже:

Затем Импортировать в вашем классе, как показано ниже:
с использованием Microsoft.VisualBasic;
Далее используйте его где хотите, как показано ниже:
if (!Information.IsNumeric(softwareVersion))
{
throw new DataException(string.Format("[{0}] is an invalid App Version! Only numeric values are supported at this time.", softwareVersion));
}
Надеюсь, что это помогает и удачи!
Хотя я бы не рекомендовал этот метод, это является правильный ответ. Не уверен, почему он был отвергнут, и, поскольку не было объяснено, почему, я проголосовал за противодействие этому :-)
Я знаю, что на это ответили по-разному, с расширениями и примерами лямбда, но комбинация обоих для простейшего решения.
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();
Для пользователей, незнакомых с методы расширения, может быть полезно включить дополнительную информацию (или, по крайней мере, окружающий статический класс, чтобы предоставить более полный пример).
Мне не нравится это решение, потому что оно вернет false для чисел с десятичной дробью. Это может быть полезно для целых чисел, но если это то, что вы хотите использовать для метода, его следует переименовать в IsInteger.
У меня немного другая версия, которая возвращает число. Я предполагаю, что в большинстве случаев после тестирования строки вы захотите использовать номер.
public bool IsNumeric(string numericString, out Double numericValue)
{
if (Double.TryParse(numericString, out numericValue))
return true;
else
return false;
}
Это модифицированная версия решения, предложенного г-ном Сииром. Я считаю, что добавление метода расширения - лучшее решение для повторного использования и простоты вызывающего метода.
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; }
}
}
}
Замените Ваше ИмяПространствоЗдесь своим фактическим NameSpace. Сохранить изменения. Теперь вы можете использовать метод расширения в любом месте вашего приложения:
bool validInput = stringVariable.IsNumeric();
Примечание: этот метод вернет истину для целых и десятичных чисел, но вернет ложь, если строка содержит запятую. Если вы хотите принимать ввод с запятыми или символами, такими как «$», я бы предложил реализовать метод для удаления этих символов сначала, а затем проверить, является ли IsNumeric.
Возможный дубликат Как определить, является ли строка числом?