Що таке C # еквівалент NaN чи IsNumeric?


103

Який найефективніший спосіб тестування вхідного рядка, чи містить він числове значення (чи навпаки, не число)? Я думаю, я можу використовувати Double.Parseабо регулярний вираз (див. Нижче), але мені було цікаво, чи є якийсь побудований спосіб зробити це, наприклад, javascript NaN()або IsNumeric()(це було VB, я не пам'ятаю?).

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

Відповіді:


176

Це не має регулярного вираження

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

Якщо потрібно, ви можете перетворити вищезазначений код у корисніший корисний метод, наприклад, загальнодоступний статичний bool IsInteger (рядок sMaybeANumber)
Gishu

@Gishu: Ти маєш рацію, якщо все, що тебе цікавить, - чи може число перетворити.
NotMe

2
Єдиною проблемою з цим є Numberоб'єкт у Javascript - плаваюче чи ціле число, тому зміна на подвійне.TryParse був би більш точним еквівалентом
Chris S

7
Можливо, ви хочете бути обережними з цим, оскільки рядки "NaN" та "Нескінченність" розбираються на a 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

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

На додаток до попередніх правильних відповідей, напевно, варто зазначити, що "Не число" (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);

Awesome C # 6 в одному рядку. Звичайно, це обмежено, оскільки він просто перевіряє лише числові символи.

Для використання достатньо ввести рядок та викликати метод, наприклад:

bool IsaNumber = "123456".IsNumeric();

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

Мені це рішення не подобається, оскільки воно поверне помилкове значення для цифр з десятковою. Це може бути корисним для цілих чисел, але якщо саме це ви хочете використовувати для методу, слід перейменувати на IsInteger
technoman23

5

Так, IsNumeric є VB. Зазвичай люди використовують метод TryParse (), хоча це трохи незграбно. Як ви запропонували, ви завжди можете написати своє.

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

}

5

Мені подобається метод розширення, але не люблю кидати винятки, якщо можливо. Я вибрав метод розширення, взявши найкращі з 2 відповідей тут.

    /// <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 лише в> 2.0 версіях .net?
Ed S.

@ChuckD: Це суб'єктивно. Ви посилаєтесь на зовнішні бібліотеки, які мають справу з json, або все це записуєте для розбору json самостійно?
shahkalpesh

@ChuckD: Запасіть мені кайфу та поясніть, чому це лайно. Для мене це просто ще один dll, який містить деякі корисні класи / функції.
shahkalpesh

@ChuckD Я думаю, що ти тут нерозумний. Функція виконує цю роботу, їх легко імпортувати, і це не так вже й велика угода.
Помилки

1
@ChuckD ви можете почати з конструктивної критики, а не починати з імпорту VisualBasic.dll для IsNumeric, якщо вас звільнять! що, очевидно, збиратиметься створити якісь резервні копії. Відповідь була ще в09 році і навіть зараз є корисною для деяких людей.
Помилки

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

Насправді, Double.NaNвін підтримується у всіх .NET версіях 2.0 та новіших версіях.


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

Double.TryParse(s, NumberStyles.Float, CultureInfo.InvariantCulture, out myNum)
Сем Харвелл

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

Я змінив тіло методу, щоб він розмістився у двох рядках, і видалив непотрібну реалізацію .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 для цілих чисел і десяткових знаків, але поверне помилковим, якщо рядок містить кому. Якщо ви хочете прийняти введення комами або символами на зразок "$", я б запропонував застосувати метод для видалення цих символів, а потім перевірити, чи є IsNumeric.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.