C # tương đương với NaN hoặc IsNumeric là gì?


102

Cách hiệu quả nhất để kiểm tra một chuỗi đầu vào cho dù nó có chứa giá trị số (hoặc ngược lại Không phải là số)? Tôi đoán tôi có thể sử dụng Double.Parsehoặc một regex (xem bên dưới) nhưng tôi đã tự hỏi liệu có một số cách được xây dựng để làm điều này, chẳng hạn như javascript NaN()hoặc IsNumeric()(đó là VB, tôi không thể nhớ?).

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

Câu trả lời:


176

Điều này không có chi phí 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
}

Ngẫu nhiên, tất cả các kiểu dữ liệu chuẩn, với ngoại lệ rõ ràng là GUID, đều hỗ trợ TryParse.

cập nhật
secretwep đưa ra rằng giá trị "2345" sẽ vượt qua bài kiểm tra ở trên dưới dạng một số. Tuy nhiên, nếu bạn cần đảm bảo rằng tất cả các ký tự trong chuỗi đều là chữ số, thì nên thực hiện một cách tiếp cận khác.

ví dụ 1 :

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

  return value;
}

hoặc nếu bạn muốn lạ mắt hơn một chút

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

cập nhật 2 (từ @stackonfire để đối phó với các chuỗi rỗng hoặc rỗng)

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

Nếu cần thiết, bạn có thể quấn đoạn code trên vào một phương pháp hữu ích hơn tiện ích như public static bool IsInteger (string sMaybeANumber)
Gishu

@Gishu: Bạn đúng nếu tất cả những gì bạn quan tâm là liệu số đó có thể chuyển đổi hay không.
NotMe

2
Vấn đề duy nhất với điều này là các Numberđối tượng trong Javascript là một phao hoặc số nguyên, vì vậy thay đổi để double.TryParse sẽ là một chính xác hơn tương đương
Chris S

7
Bạn có thể muốn cẩn thận với điều này vì các chuỗi "NaN" và "Infinity" phân tích cú pháp thành a double, nhưng nhiều người sẽ coi chúng không phải là số.
Mike Zboray

1
Một điều chỉnh Ví dụ 1 để đối phó với null hoặc rỗng chuỗi, được khác gây ISNUMBER để sai lầm trở thành sự thật: 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

Tôi thích một cái gì đó như thế này, nó cho phép bạn quyết định những gì NumberStyleđể kiểm tra.

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

7
+1 vì là người duy nhất cho đến nay tham gia Double.TryParse thay vì Int.TryParse :)
johnc

Rõ ràng đây cũng là một phương pháp mở rộng.
Anthony Mastrean

19

Ngoài các câu trả lời đúng trước đó, có lẽ đáng để chỉ ra rằng "Không phải số" (NaN) trong cách sử dụng chung của nó không tương đương với một chuỗi không thể được đánh giá là giá trị số. NaN thường được hiểu là một giá trị số được sử dụng để biểu thị kết quả của một phép tính "không thể" - trong đó kết quả là không xác định. Về mặt này, tôi muốn nói rằng việc sử dụng Javascript hơi sai lệch. Trong C #, NaN được định nghĩa như một thuộc tính của kiểu số đơn và số kép và được sử dụng để chỉ rõ ràng kết quả của phép lặn số 0. Các ngôn ngữ khác sử dụng nó để đại diện cho các giá trị "không thể" khác nhau.


11

Tôi biết điều này đã được trả lời theo nhiều cách khác nhau, với các phần mở rộng và ví dụ lambda, nhưng sự kết hợp của cả hai để có giải pháp đơn giản nhất.

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

hoặc nếu bạn đang sử dụng Visual Studio 2015 (C # 6.0 trở lên) thì

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

C # 6 tuyệt vời trên một dòng. Tất nhiên điều này bị hạn chế vì nó chỉ kiểm tra các ký tự số.

Để sử dụng, chỉ cần có một chuỗi và gọi phương thức trên đó, chẳng hạn như:

bool IsaNumber = "123456".IsNumeric();

1
Đối với những người dùng không quen với các phương thức mở rộng , có thể có lợi khi bao gồm thêm một số thông tin (hoặc ít nhất là lớp tĩnh xung quanh để cung cấp một ví dụ đầy đủ hơn).
johnnyRose

Tôi không thích giải pháp này vì nó sẽ trả về sai cho các số có số thập phân. Nó có thể hữu ích cho các số nguyên, nhưng nếu đó là những gì bạn muốn sử dụng nó cho phương pháp thì nên đổi tên thành IsInteger
technoman23

5

Yeah, IsNumeric là VB. Thông thường mọi người sử dụng phương thức TryParse (), mặc dù nó hơi rắc rối. Như bạn đã đề xuất, bạn luôn có thể viết của riêng bạn.

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

}

5

Tôi thích phương pháp mở rộng, nhưng không thích ném các ngoại lệ nếu có thể. Tôi đã chọn một phương pháp mở rộng lấy 2 câu trả lời ở đây.

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

Bạn vẫn có thể sử dụng hàm Visual Basic trong C #. Điều duy nhất bạn phải làm là chỉ cần làm theo hướng dẫn của tôi được hiển thị bên dưới:

  1. Thêm tham chiếu vào Thư viện Visual Basic bằng cách nhấp chuột phải vào dự án của bạn và chọn "Thêm tài liệu tham khảo":

nhập mô tả hình ảnh ở đây

  1. Sau đó nhập nó vào lớp của bạn như được hiển thị bên dưới:

    sử dụng Microsoft.VisualBasic;

  2. Tiếp theo sử dụng nó bất cứ nơi nào bạn muốn như hình dưới đây:

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

Hy vọng điều này sẽ giúp và may mắn!


2
Mặc dù tôi không khuyến khích phương pháp này, nhưng đó một câu trả lời chính xác. Bạn không chắc chắn lý do tại sao nó được downvoted, và vì nó không được giải thích lý do tại sao một trong hai, tôi lên-bình chọn để chống lại nó :-)
Abacus

4

VB có IsNumericchức năng. Bạn có thể tham khảo Microsoft.VisualBasic.dllvà sử dụng nó.


Bạn có thể chỉ nhận được phương thức VB đó trong> 2.0 phiên bản .net không?
Ed S.

@ChuckD: Đó là chủ quan. Bạn có tham khảo các thư viện bên ngoài xử lý json hay tự viết tất cả để phân tích cú pháp json?
shahkalpesh

@ChuckD: Hãy tha cho tôi câu chuyện và giải thích tại sao nó là tào lao. Đối với tôi, nó chỉ là một dll khác chứa một số lớp / hàm hữu ích.
shahkalpesh

@ChuckD Tôi nghĩ bạn đang không hợp lý ở đây. Hàm thực hiện công việc, dễ dàng nhập vào và nó không phải là vấn đề lớn.
Lỗi vào

1
@ChuckD bạn có thể muốn bắt đầu với những lời chỉ trích mang tính xây dựng thay vì bắt đầu với Nhập VisualBasic.dll cho IsNumeric sẽ khiến bạn bị sa thải! điều này rõ ràng sẽ làm cho một số sao lưu. Câu trả lời đã có từ năm '09 và thậm chí bây giờ có thể hữu ích cho một số người.
Lỗi vào

4

Tiện ích mở rộng đơn giản:

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

nếu tham số đầu vào là một chuỗi tại sao lại sử dụng .ToString ()?
technoman23

Tuy nhiên, câu trả lời này là tốt vì nó loại bỏ biến rác cần thiết cho phương thức TryParse, được sử dụng trong các câu trả lời như giải pháp của 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ó thể đây là một tính năng C # 3, nhưng bạn có thể sử dụng double.NaN.


2

Trên thực tế, Double.NaNđược hỗ trợ trong tất cả các phiên bản .NET 2.0 trở lên.


2

Tôi đã sử dụng đoạn mã của Chris Lively (câu trả lời đã chọn) được gói gọn trong một hàm bool như gợi ý của Gishu trong một hoặc hai năm. Tôi đã sử dụng nó để đảm bảo một số chuỗi truy vấn nhất định chỉ là số trước khi tiếp tục xử lý thêm. Tôi bắt đầu nhận được một số chuỗi truy vấn sai mà câu trả lời được đánh dấu không được xử lý, cụ thể là bất cứ khi nào dấu phẩy được chuyển sau một số như "3645" (trả về true). Đây là mod kết quả:

   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 vì thú vị. Tôi đoán đó là một câu hỏi sử dụng nhiều hơn. Nói cách khác, nếu bạn chỉ muốn đảm bảo giá trị có thể được chuyển đổi thành một số mà không gặp lỗi thì câu trả lời ban đầu của tôi là tốt. Tuy nhiên, nếu bạn lo lắng rằng tất cả các ký tự trong chuỗi thực sự là chữ số thì cần có một cách tiếp cận hoàn toàn khác
NotMe

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

0

Tôi có một phiên bản hơi khác mà trả về số. Tôi đoán rằng trong hầu hết các trường hợp sau khi kiểm tra chuỗi, bạn sẽ muốn sử dụng số.

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

0

Đây là phiên bản sửa đổi của giải pháp do Mr Siir đề xuất. Tôi thấy rằng thêm một phương thức mở rộng là giải pháp tốt nhất để tái sử dụng và đơn giản hóa phương thức gọi.

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

Tôi đã sửa đổi phần thân phương thức để vừa với 2 dòng và loại bỏ phần triển khai .ToString () không cần thiết. Đối với những người không quen thuộc với các phương pháp mở rộng, đây là cách triển khai:

Tạo một tệp lớp có tên là ExtensionMethods . Dán mã này vào:

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

Thay thế YourNameSpaceHere bằng NameSpace thực của bạn. Lưu thay đổi. Giờ đây, bạn có thể sử dụng phương thức tiện ích mở rộng ở bất kỳ đâu trong ứng dụng của mình:

bool validInput = stringVariable.IsNumeric();

Lưu ý: phương thức này sẽ trả về true cho số nguyên và số thập phân, nhưng sẽ trả về false nếu chuỗi chứa dấu phẩy. Nếu bạn muốn chấp nhận đầu vào bằng dấu phẩy hoặc ký hiệu như "$", tôi khuyên bạn nên triển khai phương pháp xóa các ký tự đó trước rồi kiểm tra xem IsNumeric hay không.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.