Berapa setara C # dari NaN atau IsNumeric?

103

Apa cara paling efisien untuk menguji string input apakah itu berisi nilai numerik (atau sebaliknya Bukan Angka)? Saya kira saya dapat menggunakan Double.Parseatau regex (lihat di bawah) tetapi saya bertanya-tanya apakah ada beberapa cara yang dibangun untuk melakukan ini, seperti javascript NaN()atau IsNumeric()(apakah itu VB, saya tidak ingat?).

public static bool IsNumeric(this string value)
{
    return Regex.IsMatch(value, "^\\d+$");
}
johnc
sumber
1
Kemungkinan duplikat dari Bagaimana cara mengidentifikasi jika sebuah string adalah angka?
Michael Freidgeim

Jawaban:

176

Ini tidak memiliki overhead regex

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

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

Kebetulan, semua tipe data standar, dengan pengecualian mencolok dari GUID, mendukung TryParse.

update
secretwep menunjukkan bahwa nilai "2345" akan lulus tes di atas sebagai angka. Namun, jika Anda perlu memastikan bahwa semua karakter dalam string adalah digit, maka pendekatan lain harus dilakukan.

contoh 1 :

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

  return value;
}

atau jika Anda ingin sedikit lebih mewah

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

update 2 (dari @stackonfire untuk menangani null atau string kosong)

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; 
}
Bukan saya
sumber
Jika perlu, Anda dapat menggabungkan kode di atas menjadi metode utilitas yang lebih bermanfaat seperti isInteger bool statis publik (string sMaybeANumber)
Gishu
@ Gishu: Anda benar jika yang Anda pedulikan hanyalah apakah nomor tersebut dapat dikonversi.
NotMe
2
Satu-satunya masalah dengan ini adalah Numberobjek di Javascript adalah float atau integer, jadi ubah ke double.TryParse akan menjadi lebih tepat setara
Chris S
7
Anda mungkin ingin berhati-hati dengan ini karena string "NaN" dan "Infinity" parse ke a double, tetapi banyak yang akan menganggapnya bukan numerik.
Mike Zboray
1
Contoh 1 yang dikoreksi untuk menangani null atau string kosong, yang sebaliknya menyebabkan IsNumber salah mengembalikan true: 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

Saya lebih suka sesuatu seperti ini, ini memungkinkan Anda memutuskan apa yang NumberStyleakan diuji.

public static Boolean IsNumeric(String input, NumberStyles numberStyle) {
    Double temp;
    Boolean result = Double.TryParse(input, numberStyle, CultureInfo.CurrentCulture, out temp);
    return result;
}
Anthony Mastrean
sumber
7
+1 untuk menjadi satu-satunya orang sejauh ini untuk Double.TryParse daripada Int.TryParse :)
johnc
Ini juga, jelas, hampir merupakan metode perluasan.
Anthony Mastrean
19

Selain jawaban benar sebelumnya, mungkin ada baiknya menunjukkan bahwa "Bukan Angka" (NaN) dalam penggunaan umumnya tidak setara dengan string yang tidak dapat dievaluasi sebagai nilai numerik. NaN biasanya dipahami sebagai nilai numerik yang digunakan untuk mewakili hasil kalkulasi "tidak mungkin" - di mana hasilnya tidak ditentukan. Dalam hal ini saya akan mengatakan penggunaan Javascript sedikit menyesatkan. Dalam C # NaN didefinisikan sebagai properti dari tipe numerik tunggal dan ganda dan digunakan untuk merujuk secara eksplisit ke hasil penyelaman nol dengan nol. Bahasa lain menggunakannya untuk mewakili nilai "tidak mungkin" yang berbeda.

Stu Mackellar
sumber
11

Saya tahu ini telah dijawab dengan berbagai cara, dengan ekstensi dan contoh lambda, tetapi kombinasi keduanya untuk solusi paling sederhana.

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

atau jika Anda menggunakan Visual Studio 2015 (C # 6.0 atau lebih tinggi) kemudian

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

Mengagumkan C # 6 dalam satu baris. Tentu saja ini dibatasi karena hanya menguji karakter numerik saja.

Untuk menggunakan, cukup gunakan string dan panggil metode di atasnya, seperti:

bool IsaNumber = "123456".IsNumeric();
Paul Bartlett
sumber
1
Untuk pengguna yang tidak terbiasa dengan metode ekstensi , mungkin bermanfaat untuk menyertakan beberapa informasi lebih lanjut (atau setidaknya kelas statis di sekitarnya untuk memberikan contoh yang lebih lengkap).
johnnyRose
Saya tidak suka solusi ini karena akan mengembalikan nilai salah untuk angka dengan desimal. Itu bisa berguna untuk bilangan bulat, tetapi jika itu ini apa yang ingin Anda menggunakannya untuk metode harus berganti nama IsInteger
technoman23
5

Ya, IsNumeric adalah VB. Biasanya orang menggunakan metode TryParse (), meskipun agak kikuk. Seperti yang Anda sarankan, Anda selalu bisa menulis sendiri.

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

}
Ed S.
sumber
5

Saya suka metode ekstensi, tapi tidak suka melempar pengecualian jika memungkinkan. Saya memilih metode ekstensi yang mengambil 2 jawaban terbaik di sini.

    /// <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;
    }
NER1808
sumber
4

Anda masih dapat menggunakan fungsi Visual Basic di C #. Satu-satunya hal yang harus Anda lakukan hanyalah mengikuti instruksi saya yang ditunjukkan di bawah ini:

  1. Tambahkan referensi ke Perpustakaan Visual Basic dengan mengklik kanan pada proyek Anda dan memilih "Tambahkan Referensi":

masukkan deskripsi gambar di sini

  1. Kemudian impor di kelas Anda seperti yang ditunjukkan di bawah ini:

    menggunakan Microsoft.VisualBasic;

  2. Selanjutnya gunakan dimanapun Anda inginkan seperti yang ditunjukkan di bawah ini:

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

Semoga membantu dan semoga berhasil!

Vincy
sumber
2
Meskipun saya tidak akan merekomendasikan metode ini, ini adalah jawaban yang benar. Tidak yakin mengapa itu diturunkan suara, dan karena tidak dijelaskan mengapa juga, saya memilih untuk menangkalnya :-)
Abacus
4

VB memiliki IsNumericfungsi. Anda dapat merujuk Microsoft.VisualBasic.dlldan menggunakannya.

shahkalpesh.dll
sumber
Bisakah Anda hanya mendapatkan metode VB di> 2.0 versi .net?
Ed S.
@ ChuckD: Itu subjektif. Apakah Anda merujuk pustaka eksternal yang menangani json atau menulis semuanya untuk mengurai json sendiri?
shahkalpesh
@ ChuckD: Biarkan saya omong kosong dan jelaskan mengapa itu omong kosong. Bagi saya, itu hanyalah dll yang berisi beberapa kelas / fungsi yang berguna.
shahkalpesh
@ChuckD Saya pikir Anda bersikap tidak masuk akal di sini. Fungsi tersebut melakukan tugasnya, mudah untuk diimpor dan itu bukan masalah besar.
Bug
1
@ChuckD Anda mungkin ingin memulai dengan kritik membangun daripada memulai dengan Mengimpor VisualBasic.dll untuk IsNumeric seharusnya membuat Anda dipecat! yang jelas akan membuat seseorang kembali. Jawabannya ada di tahun '09 dan bahkan sekarang berguna bagi sebagian orang.
Bugs
4

Ekstensi sederhana:

public static bool IsNumeric(this String str)
{
    try
    {
        Double.Parse(str.ToString());
        return true;
    }
    catch {
    }
    return false;
}
MrSiir
sumber
jika parameter input adalah string mengapa menggunakan .ToString ()?
technoman23
Jawaban ini bagus karena menghilangkan variabel sampah yang diperlukan untuk metode TryParse, yang digunakan dalam jawaban seperti solusi 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;
    }
}
Mnaouar
sumber
3

Mungkin ini adalah fitur C # 3, tetapi Anda dapat menggunakannya double.NaN.

kenny
sumber
2

Sebenarnya, Double.NaNdidukung di semua .NET versi 2.0 dan yang lebih baru.

Kucing gila
sumber
2

Saya menggunakan potongan Chris Lively (jawaban yang dipilih) yang dikemas dalam fungsi bool seperti saran Gishu selama satu atau dua tahun. Saya menggunakannya untuk memastikan string kueri tertentu hanya numerik sebelum melanjutkan dengan pemrosesan lebih lanjut. Saya mulai mendapatkan beberapa string kueri yang salah yang tidak ditangani oleh jawaban yang ditandai, khususnya, setiap kali koma diberikan setelah angka seperti "3645", (dikembalikan benar). Ini adalah mod yang dihasilkan:

   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;
      }
   }
rahasia
sumber
1 karena menarik. Saya kira ini lebih merupakan pertanyaan penggunaan. Dengan kata lain, jika Anda hanya ingin memastikan nilainya dapat diubah menjadi angka tanpa menimbulkan kesalahan maka jawaban asli saya adalah baik. Namun, jika Anda lebih khawatir bahwa semua karakter dalam string sebenarnya adalah digit, maka diperlukan pendekatan yang sama sekali berbeda
NotMe
Double.TryParse(s, NumberStyles.Float, CultureInfo.InvariantCulture, out myNum)
Sam Harwell
0

Saya memiliki versi yang sedikit berbeda yang mengembalikan nomor tersebut. Saya akan menebak bahwa dalam banyak kasus setelah menguji string Anda ingin menggunakan nomor tersebut.

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

Ini adalah versi modifikasi dari solusi yang diusulkan oleh Bapak Siir. Saya menemukan bahwa menambahkan metode ekstensi adalah solusi terbaik untuk digunakan kembali dan kesederhanaan dalam metode panggilan.

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

Saya memodifikasi tubuh metode agar sesuai pada 2 baris dan menghapus implementasi .ToString () yang tidak perlu. Bagi mereka yang tidak terbiasa dengan metode ekstensi, berikut adalah cara mengimplementasikannya:

Buat file kelas bernama ExtensionMethods . Tempel kode ini:

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

Ganti YourNameSpaceHere dengan NameSpace Anda yang sebenarnya. Simpan perubahan. Sekarang Anda dapat menggunakan metode ekstensi di mana saja di aplikasi Anda:

bool validInput = stringVariable.IsNumeric();

Catatan: metode ini akan mengembalikan nilai true untuk bilangan bulat dan desimal, tetapi akan mengembalikan nilai salah jika string berisi koma. Jika Anda ingin menerima masukan dengan koma atau simbol seperti "$", saya sarankan menerapkan metode untuk menghapus karakter tersebut terlebih dahulu kemudian menguji apakah IsNumeric.

teknisi23
sumber