NaN veya IsNumeric'in C # eşdeğeri nedir?


103

Bir girdi dizesini sayısal bir değer (veya bir Sayı Değil) içerip içermediğini test etmenin en etkili yolu nedir? Sanırım Double.Parseveya bir regex kullanabilirim (aşağıya bakın), ancak bunu yapmak için javascript NaN()veya IsNumeric()(o VB miydi, hatırlayamıyorum?) Gibi bir yöntem var mı diye merak ediyordum .

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

Yanıtlar:


176

Bunun normal ifade ek yükü yok

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

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

Bu arada, GUID'ler hariç tüm standart veri türleri, TryParse'ı destekler.

update
secretwep, "2345" değerinin yukarıdaki testi bir sayı olarak geçeceğini ortaya çıkardı. Ancak, dizedeki tüm karakterlerin rakam olduğundan emin olmanız gerekiyorsa, başka bir yaklaşım benimsenmelidir.

örnek 1 :

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

  return value;
}

ya da biraz daha süslü olmak istiyorsan

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

güncelleme 2 (@stackonfire'dan boş veya boş dizelerle uğraşmak için)

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

Gerekirse, yukarıdaki kodu genel statik bool IsInteger (string sMaybeANumber) gibi daha yararlı bir yardımcı program yöntemine sarabilirsiniz
Gishu

@Gishu: Tek umursadığın sayının dönüşüp dönüştüremeyeceğiyse haklısın.
NotMe

2
Bununla ilgili tek sorun Number, Javascript'teki nesnenin bir kayan nokta veya tamsayı olmasıdır, bu nedenle ikiye katlamak daha kesin bir eşdeğer olacaktır
Chris S

7
"NaN" ve "Infinity" dizeleri a'ya ayrıştırırken buna dikkat etmek isteyebilirsiniz double, ancak çoğu kişi bunların sayısal olmadığını düşünür.
Mike Zboray

1
Null veya boş dizelerle başa çıkmak için düzeltilmiş bir Örnek 1, aksi takdirde IsNumber'ın yanlışlıkla doğruya dönmesine neden oluyordu: 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

Böyle bir şeyi tercih ederim, neyi NumberStyletest edeceğinize karar vermenizi sağlar .

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

7
Şimdiye kadarki tek kişi olduğu için +1.Th. TryParse yerine Double. TryParse :)
johnc

Bu da tabii ki neredeyse bir uzatma yöntemidir.
Anthony Mastrean

19

Önceki doğru cevaplara ek olarak, muhtemelen "Sayı Değil" (NaN) genel kullanımında sayısal bir değer olarak değerlendirilemeyen bir dizgeye eşdeğer olmadığına işaret etmeye değer. NaN genellikle "imkansız" bir hesaplamanın sonucunu temsil etmek için kullanılan sayısal bir değer olarak anlaşılır - burada sonuç tanımsızdır. Bu açıdan Javascript kullanımının biraz yanıltıcı olduğunu söyleyebilirim. C # NaN'de, tek ve çift sayısal türlerin bir özelliği olarak tanımlanır ve sıfıra sıfır dalmanın sonucuna açıkça atıfta bulunmak için kullanılır. Diğer diller bunu farklı "imkansız" değerleri temsil etmek için kullanır.


11

Bunun uzantılar ve lambda örnekleriyle birçok farklı şekilde yanıtlandığını biliyorum, ancak en basit çözüm için ikisinin bir kombinasyonu.

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

veya Visual Studio 2015 (C # 6.0 veya üzeri) kullanıyorsanız

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

Tek satırda harika C # 6. Elbette bu sınırlıdır çünkü sadece sayısal karakterleri test eder.

Kullanmak için bir dizeye sahip olun ve üzerinde yöntemi çağırın, örneğin:

bool IsaNumber = "123456".IsNumeric();

1
Uzantı yöntemlerine aşina olmayan kullanıcılar için, biraz daha fazla bilgi (veya daha eksiksiz bir örnek sağlamak için en azından çevreleyen statik sınıf) eklemek faydalı olabilir.
johnnyRose

Bu çözümü sevmiyorum çünkü ondalık sayılar için yanlış döndürür. Tamsayılar için faydalı olabilir, ancak yöntem için kullanmak istediğiniz buysa, IsInteger olarak yeniden adlandırılmalıdır
technoman23

5

Evet, IsNumeric VB'dir. Biraz hantal olsa da, genellikle insanlar TryParse () yöntemini kullanır. Önerdiğiniz gibi, her zaman kendiniz yazabilirsiniz.

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

}

5

Uzatma yöntemini seviyorum, ancak mümkünse istisna atmayı sevmiyorum. Burada en iyi 2 yanıtı alan bir uzatma yöntemi seçtim.

    /// <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

Yine de C # 'da Visual Basic işlevini kullanabilirsiniz. Yapmanız gereken tek şey, aşağıda gösterilen talimatlarımı izlemektir:

  1. Projenize sağ tıklayıp "Referans Ekle" yi seçerek referansı Visual Basic Kitaplığına ekleyin:

görüntü açıklamasını buraya girin

  1. Ardından , aşağıda gösterildiği gibi sınıfınıza aktarın :

    Microsoft.VisualBasic kullanarak;

  2. Daha sonra , aşağıda gösterildiği gibi istediğiniz yerde kullanın :

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

Umarım bu yardımcı olur ve iyi şanslar!


2
Ben bu yöntemi tavsiye etmem da, olan bir doğru cevap. Neden olumsuz oy verildiğinden emin değilim ve neden de açıklanmadığı için, buna karşı koymak için yukarı oy kullandım :-)
Abacus

4

VB IsNumericişlevi vardır. Referans verebilir Microsoft.VisualBasic.dllve kullanabilirsiniz.


Bu VB yöntemini yalnızca> .net 2.0 sürümlerinde elde edebilir misiniz?
Ed S.

@ChuckD: Bu özneldir. Json ile ilgilenen harici kitaplıklara mı başvuruyorsunuz yoksa hepsini json'u kendiniz ayrıştırmak için mi yazıyorsunuz?
shahkalpesh

@ChuckD: Saçmalamayı bırak ve neden saçmalık olduğunu açıkla. Benim için, bazı yararlı sınıfları / işlevleri içeren başka bir dll'dir.
shahkalpesh

@ChuckD Burada mantıksız davrandığınızı düşünüyorum. İşlev işi yapar, içeri aktarmak kolaydır ve o kadar da önemli değildir.
Bugs

1
@ChuckD VisualBasic.dll dosyasını IsNumeric için içe aktarmakla başlamak yerine yapıcı eleştiriyle başlamak isteyebilirsiniz ! bu açıkça birilerini geri getirecek. Cevap '09'da geri döndü ve şimdi bile bazı insanlar için faydalı olabilir.
Bugs

4

Basit uzantı:

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

girdi parametresi bir dizeyse neden .ToString () kullanılsın?
technoman23

Bu cevap iyidir çünkü NER1808'in çözümü gibi cevaplarda kullanılan TryParse yöntemi için gerekli önemsiz değişkeni ortadan kaldırır.
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

Belki bu bir C # 3 özelliğidir, ancak kullanabilirsiniz double.NaN.



2

Chris Lively'nin bir veya iki yıl boyunca Gishu'nun önerisi gibi bir bool işlevinde kapsüllenmiş snippet'ini (seçilen yanıt) kullanıyordum. Daha sonraki işlemlere geçmeden önce belirli sorgu dizelerinin yalnızca sayısal olduğundan emin olmak için kullandım. Özellikle "3645" gibi bir sayıdan sonra virgül geçtiğinde (true döndü), işaretlenen cevabın işlemediği bazı hatalı sorgu dizeleri almaya başladım. Ortaya çıkan mod budur:

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

İlginç olduğu için +1. Sanırım daha çok kullanım sorusu. Diğer bir deyişle, değerin bir sayıya bir hata atmadan dönüştürülebildiğinden emin olmak istiyorsanız, orijinal cevabım iyidir. Bununla birlikte, dizedeki tüm karakterlerin aslında rakam olduğundan daha fazla endişeleniyorsanız, o zaman tamamen farklı bir yaklaşım gereklidir
NotMe

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

0

Numarayı döndüren biraz farklı bir versiyonum var. Çoğu durumda dizeyi test ettikten sonra sayıyı kullanmak isteyeceğinizi tahmin ediyorum.

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

0

Bu, Bay Şiir tarafından önerilen çözümün değiştirilmiş bir versiyonudur. Arama yönteminde yeniden kullanım ve basitlik için bir uzantı yöntemi eklemenin en iyi çözüm olduğunu görüyorum.

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

Yöntem gövdesini 2 satıra sığacak şekilde değiştirdim ve gereksiz .ToString () uygulamasını kaldırdım. Uzatma yöntemlerine aşina olmayanlar için nasıl uygulanacağı aşağıda açıklanmıştır:

ExtensionMethods adlı bir sınıf dosyası oluşturun . Bu koda yapıştırın:

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'ı gerçek NameSpace'inizle değiştirin . Değişiklikleri Kaydet. Artık uzantı yöntemini uygulamanızın herhangi bir yerinde kullanabilirsiniz:

bool validInput = stringVariable.IsNumeric();

Not: Bu yöntem tamsayılar ve ondalık sayılar için doğru döndürür, ancak dize virgül içeriyorsa yanlış döndürür. "$" Gibi virgül veya sembollerle girişi kabul etmek istiyorsanız, önce bu karakterleri kaldırmak için bir yöntem uygulamanızı ve ardından IsNumeric olup olmadığını test etmenizi öneririm.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.