ระบุว่าสตริงเป็นตัวเลขหรือไม่


731

ถ้าฉันมีสตริงเหล่านี้:

  1. "abc" = false

  2. "123" = true

  3. "ab2" = false

มีคำสั่งเหมือนIsNumeric()หรืออย่างอื่นที่สามารถระบุได้ว่าสตริงเป็นจำนวนที่ถูกต้องหรือไม่?


79
จากตัวอย่างของพวกเขาคุณจะเห็นว่าพวกเขาหมายถึงถ้าสตริงทั้งหมดเป็นตัวเลข
ลูคัส

47
ส่งคืน str.All (Char.IsDigit);
Mohsen

13
str.All (Char.IsDigit) จะประกาศ "3.14" เป็นเท็จเช่นเดียวกับ "-2" และ "3E14" ไม่ต้องพูดถึง: "0x10"
Harald Coppoolse

4
ขึ้นอยู่กับประเภทของหมายเลขที่คุณพยายามตรวจสอบ สำหรับตัวเลขจำนวนเต็มที่ไม่มีตัวคั่น (เช่นสตริงของตัวเลขทศนิยม) การตรวจสอบนี้ใช้งานได้และเป็นคำตอบเดียวกับที่ยอมรับและเป็นหนึ่งใน OP
Alex Mazzariol

1
@Lucas ขอบคุณสำหรับความคิดเห็นของคุณคุณไม่มีความคิดว่านานแค่ไหนที่ฉันพยายามแยกสตริงเป็นสองเท่าของ int และสงสัยว่าทำไมมันถึงล้มเหลว ...
Novastorm

คำตอบ:


1160
int n;
bool isNumeric = int.TryParse("123", out n);

อัปเดตตั้งแต่ C # 7:

var isNumeric = int.TryParse("123", out int n);

หรือหากคุณไม่ต้องการหมายเลขคุณสามารถยกเลิกพารามิเตอร์ out ได้

var isNumeric = int.TryParse("123", out _);

var s จะถูกแทนที่ด้วยประเภทของตน!


126
แม้ว่าฉันจะใช้ double.TryParse เนื่องจากเราต้องการทราบว่าเป็นตัวเลขหรือไม่
John Gietzen

5
ฟังก์ชั่นจะกลับมาจริงถ้าฉันส่งสตริงเป็น "-123" หรือ "+123" ฉันเข้าใจว่าจำนวนเต็มมีค่าบวกและลบ แต่ถ้าสตริงนี้มาจากผู้ใช้ป้อนกล่องข้อความก็ควรกลับเท็จ
2323308

9
นี่เป็นวิธีแก้ปัญหาที่ดีจนกระทั่งผู้ใช้ป้อนค่าเกิน -2,147,483,648 ถึง 2,147,483,647 จากนั้นจึงล้มเหลวอย่างเงียบ ๆ
BlackTigerX

ลองแยก 0,60 (นั่นคือจุลภาค!) มันเป็นจำนวนที่ไม่ถูกต้อง แต่จะถูกแยกเป็น 60!
Paul Zahra

2
ฉันชอบที่จะมีวิธีการขยายสำหรับการตรวจสอบนี้: public static bool IsNumeric(this string text) { double _out; return double.TryParse(text, out _out); }
ฮามิด Naeemi

350

สิ่งนี้จะคืนค่าจริงถ้าinputเป็นตัวเลขทั้งหมด ไม่รู้ว่ามันดีกว่าTryParseนี้ไหม แต่มันก็ใช้ได้

Regex.IsMatch(input, @"^\d+$")

ถ้าคุณเพียงต้องการที่จะรู้ว่าถ้ามันมีหนึ่งหรือมากกว่าตัวเลขผสมกับตัวละครที่ปล่อยออกและ^ +$

Regex.IsMatch(input, @"\d")

แก้ไข: จริง ๆ แล้วฉันคิดว่ามันดีกว่า TryParse เพราะสตริงที่ยาวมากอาจล้นทริปเปิ้ลได้


2
การสร้าง regex ครั้งเดียวและทั้งหมดจะมีประสิทธิภาพมากกว่า
Clément

2
@CFP +1 ... RegEx ดีกว่าฟังก์ชั่นปกติเสมอเมื่อใช้งานได้!
MAXE

19
@MAXE: ฉันจะไม่เห็นด้วย การตรวจสอบนิพจน์ปกติค่อนข้างช้าดังนั้นจึงมีวิธีแก้ปัญหาที่ดีกว่าหากประสิทธิภาพอยู่ในระหว่างการพิจารณา
Michal B.

7
แก้ไข: คุณสามารถเพิ่มRegexOptions.Compiledเป็นพารามิเตอร์หากคุณเรียกใช้หลายพันเหล่านี้เพื่อเพิ่มความเร็วที่เป็นไปได้Regex.IsMatch(x.BinNumber, @"^\d+$", RegexOptions.Compiled)
Simon_Weaver

9
จะล้มเหลวในเชิงลบและสิ่งต่าง ๆ ด้วย.
Noctis

199

คุณยังสามารถใช้:

stringTest.All(char.IsDigit);

มันจะกลับมาtrueสำหรับตัวเลขตัวเลขทั้งหมด (ไม่float) และfalseถ้าสตริงการป้อนข้อมูลเป็นตัวอักษรและตัวเลขใด ๆ

โปรดทราบ : stringTestไม่ควรเป็นสตริงว่างเนื่องจากจะผ่านการทดสอบว่าเป็นตัวเลข


20
มันเจ๋งมาก สิ่งหนึ่งที่ควรระวัง: สตริงว่างจะผ่านการทดสอบว่าเป็นตัวเลข
dan-gph

2
@ dan-gph: ฉันดีใจที่คุณชอบมัน ใช่คุณถูกต้อง. ฉันได้อัปเดตบันทึกย่อด้านบนแล้ว ขอบคุณ!
Kunal Goel

1
สิ่งนี้จะไม่ทำงานสำหรับกรณีทศนิยม การทดสอบที่เหมาะสมจะเป็น stringTest.All (l => char.IsDigit (l) || '.' == l || '-' == l);
Salman Hasrat Khan

ขอขอบคุณสำหรับการป้อนข้อมูลของคุณซัลมานเพื่อตรวจสอบเฉพาะทศนิยมออกจากสตริงคุณสามารถไป - ถ้า (Decimal.TryParse (stringTest2 ออกค่า)) {/ * ใช่ทศนิยม/} else {/ไม่มีไม่ได้เป็นสิบ * / }
Kunal Goel

6
Salman ไม่ใช่เรื่องง่าย - สิ่งนี้จะผ่าน..--..--เป็นหมายเลขที่ถูกต้อง ไม่ชัดเจน
Flynn1179

133

ฉันใช้ฟังก์ชั่นนี้หลายครั้ง:

public static bool IsNumeric(object Expression)
{
    double retNum;

    bool isNum = Double.TryParse(Convert.ToString(Expression), System.Globalization.NumberStyles.Any, System.Globalization.NumberFormatInfo.InvariantInfo, out retNum);
    return isNum;
}

แต่คุณสามารถใช้;

bool b1 = Microsoft.VisualBasic.Information.IsNumeric("1"); //true
bool b2 = Microsoft.VisualBasic.Information.IsNumeric("1aa"); // false

จากการเปรียบเทียบตัวเลือก IsNumeric

ข้อความแสดงแทน
(ที่มา: aspalliance.com )

ข้อความแสดงแทน
(ที่มา: aspalliance.com )


80
อ้างอิง Microsoft.VisualBasic.dll จากแอป C # eww: P
Lucas

ฉันไม่มีปัญหาในการใช้ "IsNumeric" มันใช้งานได้ดี นอกจากนี้คุณจะเห็นได้ว่า TryParse และ IsNumeric นั้นมีประสิทธิภาพแตกต่างกันเล็กน้อย โปรดจำไว้ว่า TryParse เป็นของใหม่ใน 2.0 และก่อนหน้านั้นควรใช้ IsNumeric ซึ่งเป็นกลยุทธ์อื่น ๆ
เนลสันมิแรนดา

10
IsNumeric () ของ VB.NET ใช้ double.TryParse () ภายในหลังจากจำนวน gyrations ที่ต้องการ (เหนือสิ่งอื่นใด) สำหรับความเข้ากันได้ของ VB6 หากคุณไม่ต้องการความเข้ากันได้ double.TryParse () นั้นใช้งานง่ายและช่วยให้คุณไม่ต้องสูญเสียความทรงจำด้วยการโหลด Microsoft.VisualBasic.dll ในกระบวนการของคุณ
Euro Micelli

4
บันทึกย่ออย่างรวดเร็ว: การใช้นิพจน์ทั่วไปจะเร็วขึ้นมากถ้าคุณจัดการให้มีเครื่องสถานะ จำกัด พื้นฐานที่สร้างขึ้นเพียงครั้งเดียวและสำหรับทั้งหมด โดยทั่วไปการสร้างเครื่องรัฐใช้ O (2 ^ n) โดยที่ n คือความยาวของ regex ในขณะที่การอ่านคือ O (k) โดยที่ k คือความยาวของสตริงที่ค้นหา ดังนั้นการสร้าง regex ใหม่ทุกครั้งที่มีอคติ
Clément

2
@ Lucas จริงๆแล้วมีบางสิ่งที่ดีจริง ๆ ในนั้นเช่น csv parser เต็ม ไม่มีเหตุผลที่จะไม่ใช้มันหากมีอยู่ในนั้น
Nyerguds

32

นี่อาจเป็นตัวเลือกที่ดีที่สุดใน C #

หากคุณต้องการทราบว่าสตริงมีทั้งจำนวน (จำนวนเต็ม):

string someString;
// ...
int myInt;
bool isNumerical = int.TryParse(someString, out myInt);

กระบวนการ TryParse วิธีจะพยายามแปลงสตริงเป็นตัวเลข (จำนวนเต็ม) และหากสำเร็จจะส่งคืนจริงและใส่ตัวเลขที่เกี่ยวข้องใน myInt หากไม่สามารถทำได้จะส่งคืนค่าเท็จ

วิธีแก้ปัญหาโดยใช้int.Parse(someString)ทางเลือกที่แสดงในคำตอบอื่น ๆ นั้นใช้งานได้ช้ากว่ามากเพราะการโยนข้อยกเว้นมีราคาแพง TryParse(...)ถูกเพิ่มในภาษา C # ในเวอร์ชัน 2 และจนกว่าคุณจะไม่มีทางเลือก ตอนนี้คุณ: คุณควรหลีกเลี่ยงParse()ทางเลือก

หากคุณต้องการรับตัวเลขทศนิยมคลาสทศนิยมก็มี.TryParse(...)วิธีการเช่นกัน แทนที่ int ด้วยทศนิยมในการสนทนาด้านบนและใช้หลักการเดียวกันนี้


ทำไม TryParse ถึงดีกว่าการเปรียบเทียบอักขระทั้งหมดด้วยอักขระจำนวนเต็ม?
Arjang

25

คุณสามารถใช้วิธีการแบบ TryParse ในตัวสำหรับหลายประเภทข้อมูลเพื่อดูว่าสายอักขระที่มีปัญหาจะผ่านหรือไม่

ตัวอย่าง.

decimal myDec;
var Result = decimal.TryParse("123", out myDec);

ผลลัพธ์จะ = True

decimal myDec;
var Result = decimal.TryParse("abc", out myDec);

ผลลัพธ์ก็จะ = เป็นเท็จ


ฉันคิดว่าฉันอาจทำเช่นนั้นในไวยากรณ์สไตล์ VB มากกว่า C # แต่ใช้กฎเดียวกัน
TheTXI

22

ในกรณีที่คุณไม่ต้องการใช้ int.Parse หรือ double.Parse คุณสามารถหมุนของคุณเองด้วยสิ่งนี้:

public static class Extensions
{
    public static bool IsNumeric(this string s)
    {
        foreach (char c in s)
        {
            if (!char.IsDigit(c) && c != '.')
            {
                return false;
            }
        }

        return true;
    }
}

7
เกิดอะไรขึ้นถ้าพวกเขาหมายถึงจำนวนเต็มเท่านั้น? สถานที่เกี่ยวกับ '.' ตัวคั่นกลุ่มไม่ใช่เครื่องหมายจุลภาค (เช่น pt-Br) หรือไม่ แล้วจำนวนลบล่ะ? ตัวแยกกลุ่ม (เครื่องหมายจุลภาคเป็นภาษาอังกฤษ) สัญลักษณ์สกุลเงิน? TryParse () สามารถจัดการสิ่งเหล่านี้ได้ตามต้องการโดยใช้ NumberStyles และ IFormatProvider
Lucas

โอ้โหฉันชอบเวอร์ชั่นทั้งหมดดีกว่า ฉันไม่เคยใช้วิธีการส่วนขยายนั้นเป็นการโทรที่ดี แม้ว่ามันควรจะเป็น s.ToCharArray (). All (.. ) สำหรับจุดที่สองของคุณผมได้ยินยาซึ่งเป็นเหตุผลที่ผมต้นด้วยถ้าคุณไม่ต้องการที่จะใช้ int.Parse .... (ซึ่งฉันสมมติว่ามีค่าใช้จ่ายมากขึ้น ... )
BFree

11
1.3.3.8.5 ไม่ใช่ตัวเลขจริง ๆ ในขณะที่ 1.23E5 คือ
Clément

4
ตรรกะมีข้อบกพร่อง -1
Russel Yang

1
@Lucas ฉันยอมรับว่า TryParse จัดการได้มากกว่า แต่บางครั้งก็ไม่จำเป็น ฉันแค่ต้องตรวจสอบกล่องหมายเลขบัตรเครดิตของฉัน (ซึ่งสามารถมีตัวเลขได้เท่านั้น) โซลูชันนี้เกือบจะเร็วกว่าการลองแยกวิเคราะห์
Millie Smith

14

หากคุณต้องการจับตัวเลขที่กว้างขึ้นในขณะที่is_numericของ PHP และคุณสามารถใช้สิ่งต่อไปนี้

// From PHP documentation for is_numeric
// (http://php.net/manual/en/function.is-numeric.php)

// Finds whether the given variable is numeric.

// Numeric strings consist of optional sign, any number of digits, optional decimal part and optional
// exponential part. Thus +0123.45e6 is a valid numeric value.

// Hexadecimal (e.g. 0xf4c3b00c), Binary (e.g. 0b10100111001), Octal (e.g. 0777) notation is allowed too but
// only without sign, decimal and exponential part.
static readonly Regex _isNumericRegex =
    new Regex(  "^(" +
                /*Hex*/ @"0x[0-9a-f]+"  + "|" +
                /*Bin*/ @"0b[01]+"      + "|" + 
                /*Oct*/ @"0[0-7]*"      + "|" +
                /*Dec*/ @"((?!0)|[-+]|(?=0+\.))(\d*\.)?\d+(e\d+)?" + 
                ")$" );
static bool IsNumeric( string value )
{
    return _isNumericRegex.IsMatch( value );
}

ทดสอบหน่วย:

static void IsNumericTest()
{
    string[] l_unitTests = new string[] { 
        "123",      /* TRUE */
        "abc",      /* FALSE */
        "12.3",     /* TRUE */
        "+12.3",    /* TRUE */
        "-12.3",    /* TRUE */
        "1.23e2",   /* TRUE */
        "-1e23",    /* TRUE */
        "1.2ef",    /* FALSE */
        "0x0",      /* TRUE */
        "0xfff",    /* TRUE */
        "0xf1f",    /* TRUE */
        "0xf1g",    /* FALSE */
        "0123",     /* TRUE */
        "0999",     /* FALSE (not octal) */
        "+0999",    /* TRUE (forced decimal) */
        "0b0101",   /* TRUE */
        "0b0102"    /* FALSE */
    };

    foreach ( string l_unitTest in l_unitTests )
        Console.WriteLine( l_unitTest + " => " + IsNumeric( l_unitTest ).ToString() );

    Console.ReadKey( true );
}

โปรดทราบว่าเพียงเพราะค่าเป็นตัวเลขไม่ได้หมายความว่าสามารถแปลงเป็นประเภทตัวเลขได้ ตัวอย่างเช่น"999999999999999999999999999999.9999999999"เป็นค่าตัวเลขที่ถูกต้อง perfeclty แต่จะไม่พอดีกับประเภทตัวเลข. NET (ไม่ใช่หนึ่งที่กำหนดไว้ในไลบรารีมาตรฐานนั่นคือ)


ไม่พยายามเป็นสมาร์ทอเล็กซ์ที่นี่ แต่ดูเหมือนว่าจะล้มเหลวสำหรับสตริง "0" Regex ของฉันไม่มีอยู่จริง มีการบิดง่ายสำหรับที่? ฉันได้รับ "0" และอาจเป็น "0.0" และแม้แต่ "-0.0" เป็นตัวเลขที่ใช้ได้
Steve Hibbert

@SteveHibbert - ทุกคนรู้ว่า "0" ไม่ใช่ตัวเลข! อย่างจริงจังแม้ว่า ... ปรับ regex ให้ตรงกับ 0
JDB ยังคงจดจำ Monica

อืมฉันเป็นหรือยังไม่รู้จัก "0" เป็นตัวเลขใช่หรือไม่
Steve Hibbert

1
เป็นคนขี้เกียจและไม่รู้เรื่องเลยฉันจึงตัดโค้ดด้านบนซึ่งดูเหมือนว่าจะมีการเปลี่ยนแปลงประเภท "0.0" ฉันรันการทดสอบเพื่อตรวจสอบว่าสตริง "0" กำลังรัน. IsNumeric () และนั่นส่งกลับค่าเท็จ ฉันคิดว่าการทดสอบ Octal จะคืนค่าจริงให้กับทุกสิ่งที่มีตัวเลขสองตัวอักษรตัวแรกที่เป็นศูนย์ (และที่สองคือศูนย์ถึงเจ็ด) แต่จะกลับเท็จเป็นไขมันใหญ่เหงาของตัวเอง หากคุณทดสอบ "0" ด้วยรหัสข้างต้นคุณได้รับเท็จหรือไม่ ขอโทษถ้าฉันรู้ regex เพิ่มเติมฉันจะสามารถให้ข้อเสนอแนะที่ดีกว่า จะต้องอ่านให้มากขึ้น
Steve Hibbert

1
! Doh! เพียงแค่อ่านความคิดเห็นของคุณข้างต้นอีกครั้งฉันพลาดเครื่องหมายดอกจันเพิ่มเติมฉันแค่อัพเดตทศนิยม เมื่อใช้งานแล้วคุณจะถูกต้อง "0" IsNumeric ขออภัยในความโปรดปรานและขอขอบคุณสำหรับการอัปเดตเป็นอย่างมากหวังว่าจะช่วยให้คนอื่น ๆ จำเป็นมาก
Steve Hibbert

14

ฉันรู้ว่านี่เป็นเธรดเก่า แต่ไม่มีคำตอบใดที่ทำให้ฉัน - ไม่มีประสิทธิภาพหรือไม่ห่อหุ้มเพื่อนำมาใช้ใหม่ได้ง่าย ฉันต้องการตรวจสอบให้แน่ใจว่ามันส่งคืนเท็จถ้าสตริงว่างเปล่าหรือว่างเปล่า TryParse คืนค่าเป็นจริงในกรณีนี้ (สตริงว่างไม่ทำให้เกิดข้อผิดพลาดเมื่อแยกเป็นตัวเลข) ดังนั้นนี่คือวิธีการขยายสตริงของฉัน:

public static class Extensions
{
    /// <summary>
    /// Returns true if string is numeric and not empty or null or whitespace.
    /// Determines if string is numeric by parsing as Double
    /// </summary>
    /// <param name="str"></param>
    /// <param name="style">Optional style - defaults to NumberStyles.Number (leading and trailing whitespace, leading and trailing sign, decimal point and thousands separator) </param>
    /// <param name="culture">Optional CultureInfo - defaults to InvariantCulture</param>
    /// <returns></returns>
    public static bool IsNumeric(this string str, NumberStyles style = NumberStyles.Number,
        CultureInfo culture = null)
    {
        double num;
        if (culture == null) culture = CultureInfo.InvariantCulture;
        return Double.TryParse(str, style, culture, out num) && !String.IsNullOrWhiteSpace(str);
    }
}

ใช้งานง่าย:

var mystring = "1234.56789";
var test = mystring.IsNumeric();

หรือหากคุณต้องการทดสอบหมายเลขประเภทอื่นคุณสามารถระบุ 'สไตล์' ดังนั้นในการแปลงตัวเลขด้วยเลขชี้กำลังคุณสามารถใช้:

var mystring = "5.2453232E6";
var test = mystring.IsNumeric(style: NumberStyles.AllowExponent);

หรือเพื่อทดสอบสตริง Hex ที่มีศักยภาพคุณสามารถใช้:

var mystring = "0xF67AB2";
var test = mystring.IsNumeric(style: NumberStyles.HexNumber)

พารามิเตอร์ 'culture' ซึ่งเป็นตัวเลือกสามารถใช้ในวิธีเดียวกันได้

มันถูก จำกัด โดยไม่สามารถแปลงสตริงที่ใหญ่เกินไปที่จะอยู่ใน double แต่มันเป็นข้อกำหนดที่ จำกัด และฉันคิดว่าถ้าคุณกำลังทำงานกับตัวเลขที่ใหญ่กว่านี้คุณอาจต้องจัดการหมายเลขพิเศษเพิ่มเติม ฟังก์ชั่นต่อไป


2
ใช้งานได้ดียกเว้น Double.TryParse ไม่รองรับ NumberStyles.HexNumber ดู MSDN DoubleTryParse เหตุผลใดที่คุณลองใช้ TryParse ก่อนตรวจสอบ IsNullOrWhiteSpace? TryParse คืนค่าเท็จถ้า IsNullOrWhiteSpace ไม่ใช่หรือไม่
Harald Coppoolse

10

คุณสามารถใช้ TryParse เพื่อพิจารณาว่าสามารถแยกสตริงเป็นจำนวนเต็มได้หรือไม่

int i;
bool bNum = int.TryParse(str, out i);

บูลีนจะบอกคุณว่ามันใช้งานได้หรือไม่


9

หากคุณต้องการตรวจสอบว่าสตริงเป็นตัวเลขหรือไม่ (ฉันสมมติว่าเป็นสตริงเพราะถ้าเป็นตัวเลขให้คุณรู้ว่ามันเป็นสตริง)

  • โดยไม่ต้อง regex และ
  • ใช้รหัสของ Microsoft ให้มากที่สุด

คุณสามารถทำได้:

public static bool IsNumber(this string aNumber)
{
     BigInteger temp_big_int;
     var is_number = BigInteger.TryParse(aNumber, out temp_big_int);
     return is_number;
}

สิ่งนี้จะดูแลสิ่งสกปรกตามปกติ:

  • เครื่องหมายลบ (-) หรือเครื่องหมายบวก (+) ในตอนเริ่มต้น
  • มีอักขระทศนิยมBigIntegers จะไม่แยกตัวเลขด้วยจุดทศนิยม (ดังนั้น: BigInteger.Parse("3.3")จะโยนข้อยกเว้นและTryParseสำหรับเดียวกันจะกลับเท็จ)
  • ไม่ตลกไม่ใช่ตัวเลข
  • ครอบคลุมกรณีที่จำนวนใหญ่กว่าการใช้งานปกติ Double.TryParse

คุณจะต้องเพิ่มการอ้างอิงSystem.Numericsและมี using System.Numerics;ชั้นเรียนของคุณ (ดีที่สองคือโบนัสฉันเดา :)


8

ฉันเดาว่าคำตอบนี้จะหายไประหว่างคำตอบอื่น ๆ แต่ต่อไปนี้

ฉันสิ้นสุดขึ้นกับคำถามนี้ผ่านทาง Google เพราะฉันอยากจะตรวจสอบว่าstringเป็นnumericเพื่อที่ฉันก็สามารถใช้double.Parse("123")แทนTryParse()วิธีการ

ทำไม? เพราะมันน่ารำคาญที่จะต้องประกาศoutตัวแปรและตรวจสอบผลลัพธ์TryParse()ก่อนที่คุณจะรู้ว่าการแยกวิเคราะห์ล้มเหลวหรือไม่ ฉันต้องการใช้ternary operatorเพื่อตรวจสอบว่าstringเป็นnumericalแล้วแค่แยกในนิพจน์ที่ประกอบไปด้วยประโยคแรกหรือให้ค่าเริ่มต้นในนิพจน์ที่สาม

แบบนี้:

var doubleValue = IsNumeric(numberAsString) ? double.Parse(numberAsString) : 0;

มันสะอาดกว่า:

var doubleValue = 0;
if (double.TryParse(numberAsString, out doubleValue)) {
    //whatever you want to do with doubleValue
}

ฉันทำสองสามextension methodsกรณีนี้:


ส่วนต่อขยายวิธีที่หนึ่ง

public static bool IsParseableAs<TInput>(this string value) {
    var type = typeof(TInput);

    var tryParseMethod = type.GetMethod("TryParse", BindingFlags.Static | BindingFlags.Public, Type.DefaultBinder,
        new[] { typeof(string), type.MakeByRefType() }, null);
    if (tryParseMethod == null) return false;

    var arguments = new[] { value, Activator.CreateInstance(type) };
    return (bool) tryParseMethod.Invoke(null, arguments);
}

ตัวอย่าง:

"123".IsParseableAs<double>() ? double.Parse(sNumber) : 0;

เนื่องจากIsParseableAs()พยายามแยกสตริงเป็นชนิดที่เหมาะสมแทนที่จะตรวจสอบว่าสตริงเป็น "ตัวเลข" ควรปลอดภัยหรือไม่ และคุณยังสามารถใช้มันสำหรับประเภทที่ไม่ใช่ตัวเลขที่มีTryParse()วิธีเช่นDateTimeวิธีการเช่น

วิธีนี้ใช้การไตร่ตรองและคุณจะต้องโทรหาTryParse()วิธีสองครั้งซึ่งแน่นอนว่าไม่ได้มีประสิทธิภาพ แต่ไม่ใช่ทุกสิ่งที่จะต้องได้รับการปรับให้เหมาะสมที่สุดบางครั้งความสะดวกสบายก็มีความสำคัญมากกว่า

วิธีนี้ยังสามารถใช้ในการแยกรายการสตริงตัวเลขลงในรายการdoubleหรือประเภทอื่น ๆ ด้วยค่าเริ่มต้นโดยไม่ต้องจับข้อยกเว้นใด ๆ :

var sNumbers = new[] {"10", "20", "30"};
var dValues = sNumbers.Select(s => s.IsParseableAs<double>() ? double.Parse(s) : 0);

วิธีการขยายสอง

public static TOutput ParseAs<TOutput>(this string value, TOutput defaultValue) {
    var type = typeof(TOutput);

    var tryParseMethod = type.GetMethod("TryParse", BindingFlags.Static | BindingFlags.Public, Type.DefaultBinder,
        new[] { typeof(string), type.MakeByRefType() }, null);
    if (tryParseMethod == null) return defaultValue;

    var arguments = new object[] { value, null };
    return ((bool) tryParseMethod.Invoke(null, arguments)) ? (TOutput) arguments[1] : defaultValue;
}

วิธีขยายนี้ช่วยให้คุณแยกstringเป็นใด ๆtypeที่มีTryParse()วิธีการและยังช่วยให้คุณระบุค่าเริ่มต้นที่จะกลับมาถ้าการแปลงล้มเหลว

สิ่งนี้ดีกว่าการใช้ผู้ประกอบการที่ประกอบไปด้วยวิธีการขยายด้านบนเพราะมันจะทำการแปลงเพียงครั้งเดียว มันยังคงใช้การสะท้อนแม้ว่า ...

ตัวอย่าง:

"123".ParseAs<int>(10);
"abc".ParseAs<int>(25);
"123,78".ParseAs<double>(10);
"abc".ParseAs<double>(107.4);
"2014-10-28".ParseAs<DateTime>(DateTime.MinValue);
"monday".ParseAs<DateTime>(DateTime.MinValue);

ขาออก:

123
25
123,78
107,4
28.10.2014 00:00:00
01.01.0001 00:00:00

4
ฉันเชื่อว่าคุณอาจคิดค้นวิธีที่ไม่มีประสิทธิภาพมากที่สุดวิธีหนึ่งที่ฉันเคยเห็น ไม่เพียง แต่คุณจะวิเคราะห์สตริงสองครั้ง (ในกรณีที่วิเคราะห์ได้) คุณยังเรียกฟังก์ชันการสะท้อนหลาย ๆ ครั้งเพื่อทำ และในที่สุดคุณไม่ต้องบันทึกการกดแป้นใด ๆ โดยใช้วิธีการขยาย
JDB ยังคงจดจำโมนิก้า

ขอบคุณสำหรับการทำซ้ำสิ่งที่ฉันเขียนเองในวรรคสองถึงครั้งสุดท้าย นอกจากนี้หากคุณใช้ตัวอย่างสุดท้ายของฉันเข้าสู่บัญชีคุณสามารถบันทึกการกดแป้นพิมพ์ได้อย่างแน่นอนโดยใช้วิธีส่วนขยายนี้ คำตอบนี้ไม่ได้อ้างว่าเป็นวิธีการแก้ปัญหาที่วิเศษสำหรับปัญหาใด ๆ มันเป็นเพียงตัวอย่างรหัส ใช้หรือไม่ใช้ ฉันคิดว่ามันสะดวกเมื่อใช้อย่างถูกต้อง และมันมีตัวอย่างของวิธีการขยายและการไตร่ตรองบางทีบางคนสามารถเรียนรู้จากมันได้
Hein Andre Grønnestad

5
คุณเคยลองvar x = double.TryParse("2.2", new double()) ? double.Parse("2.2") : 0.0;ไหม
JDB ยังคงจำโมนิก้า

2
ใช่และมันไม่ทำงาน Argument 2 must be passed with the 'out' keywordและถ้าคุณระบุoutเช่นเดียวกับที่คุณได้รับnew A ref or out argument must be an assignable variable
Hein Andre Grønnestad

1
ประสิทธิภาพการทำงานของ TryParse ดีกว่าที่เปิดเผยทั้งหมดในที่นี้ ผลการทดลอง: TryParse 8 Regex 20 PHP IsNumeric 30 Reflections TryParse 31 รหัสทดสอบdotnetfiddle.net/x8GjAF
prampe

7

หากคุณต้องการทราบว่าสตริงเป็นตัวเลขหรือไม่คุณสามารถลองแยกวิเคราะห์ได้เสมอ:

var numberString = "123";
int number;

int.TryParse(numberString , out number);

โปรดทราบว่าTryParseส่งกลับ a boolซึ่งคุณสามารถใช้เพื่อตรวจสอบว่าการแยกวิเคราะห์ของคุณประสบความสำเร็จ



4

UPDATE ของคำตอบ Kunal Noel

stringTest.All(char.IsDigit);
// This returns true if all characters of the string are digits.

แต่สำหรับกรณีนี้เรามีสตริงว่างเปล่าที่จะผ่านการทดสอบดังนั้นคุณสามารถ:

if (!string.IsNullOrEmpty(stringTest) && stringTest.All(char.IsDigit)){
   // Do your logic here
}

4

วิธีการแก้ปัญหาที่มีความยืดหยุ่นที่ดีที่สุดกับสุทธิในตัว char.IsDigitcalled- มันทำงานได้กับตัวเลขยาวไม่ จำกัด มันจะกลับมาจริงถ้าตัวละครแต่ละตัวเป็นตัวเลข ฉันใช้มันบ่อยครั้งโดยไม่มีปัญหาและวิธีแก้ปัญหาที่ทำความสะอาดง่ายกว่าที่ฉันเคยพบมา ฉันทำวิธีการตัวอย่างพร้อมใช้งานแล้ว นอกจากนี้ฉันได้เพิ่มการตรวจสอบสำหรับโมฆะและอินพุตว่าง ดังนั้นวิธีนี้จึงกันกระสุนได้ทั้งหมด

public static bool IsNumeric(string strNumber)
    {
        if (string.IsNullOrEmpty(strNumber))
        {
            return false;
        }
        else
        {
            int numberOfChar = strNumber.Count();
            if (numberOfChar > 0)
            {
                bool r = strNumber.All(char.IsDigit);
                return r;
            }
            else
            {
                return false;
            }
        }
    }


2

ใช้วิธีการขยายเหล่านี้เพื่อแยกความแตกต่างระหว่างการตรวจสอบอย่างชัดเจนว่าสตริงเป็นตัวเลขและถ้าสตริงมีตัวเลข 0-9 เท่านั้น

public static class ExtensionMethods
{
    /// <summary>
    /// Returns true if string could represent a valid number, including decimals and local culture symbols
    /// </summary>
    public static bool IsNumeric(this string s)
    {
        decimal d;
        return decimal.TryParse(s, System.Globalization.NumberStyles.Any, System.Globalization.CultureInfo.CurrentCulture, out d);
    }

    /// <summary>
    /// Returns true only if string is wholy comprised of numerical digits
    /// </summary>
    public static bool IsNumbersOnly(this string s)
    {
        if (s == null || s == string.Empty)
            return false;

        foreach (char c in s)
        {
            if (c < '0' || c > '9') // Avoid using .IsDigit or .IsNumeric as they will return true for other characters
                return false;
        }

        return true;
    }
}

2
public static bool IsNumeric(this string input)
{
    int n;
    if (!string.IsNullOrEmpty(input)) //.Replace('.',null).Replace(',',null)
    {
        foreach (var i in input)
        {
            if (!int.TryParse(i.ToString(), out n))
            {
                return false;
            }

        }
        return true;
    }
    return false;
}

1

หวังว่านี่จะช่วยได้

string myString = "abc";
double num;
bool isNumber = double.TryParse(myString , out num);

if isNumber 
{
//string is number
}
else
{
//string is not a number
}

0

ดึงการอ้างอิงถึง Visual Basic ในโครงการของคุณและใช้วิธีการ Information.IsNumeric เช่นที่แสดงด้านล่างและสามารถจับลอยเช่นเดียวกับจำนวนเต็มซึ่งแตกต่างจากคำตอบข้างต้นซึ่งจับ ints เท่านั้น

    // Using Microsoft.VisualBasic;

    var txt = "ABCDEFG";

    if (Information.IsNumeric(txt))
        Console.WriteLine ("Numeric");

IsNumeric("12.3"); // true
IsNumeric("1"); // true
IsNumeric("abc"); // false

ปัญหาที่อาจเกิดขึ้นกับวิธีนี้คือIsNumericการวิเคราะห์ตัวละครของสตริง ดังนั้นจำนวนที่ชอบ9999999999999999999999999999999999999999999999999999999999.99999999999จะลงทะเบียนเป็นTrueแม้ว่าจะไม่มีวิธีที่จะแสดงหมายเลขนี้โดยใช้ประเภทตัวเลขมาตรฐาน
JDB ยังคงจดจำโมนิก้า

0

ลอง reges ด้านล่าง

new Regex(@"^\d{4}").IsMatch("6")    // false
new Regex(@"^\d{4}").IsMatch("68ab") // false
new Regex(@"^\d{4}").IsMatch("1111abcdefg") ```

0

คำตอบทั้งหมดมีประโยชน์ แต่ในขณะที่ค้นหาวิธีแก้ปัญหาที่ค่าตัวเลขเป็น 12 หลักหรือมากกว่า (ในกรณีของฉัน) จากนั้นในขณะที่ตรวจแก้จุดบกพร่องฉันพบโซลูชันต่อไปนี้มีประโยชน์:

double tempInt = 0;
bool result = double.TryParse("Your_12_Digit_Or_more_StringValue", out tempInt);

ตัวแปรผลลัพธ์จะให้คุณจริงหรือเท็จ



-7
//To my knowledge I did this in a simple way
static void Main(string[] args)
{
    string a, b;
    int f1, f2, x, y;
    Console.WriteLine("Enter two inputs");
    a = Convert.ToString(Console.ReadLine());
    b = Console.ReadLine();
    f1 = find(a);
    f2 = find(b);

    if (f1 == 0 && f2 == 0)
    {
        x = Convert.ToInt32(a);
        y = Convert.ToInt32(b);
        Console.WriteLine("Two inputs r number \n so that addition of these text box is= " + (x + y).ToString());
    }
    else
        Console.WriteLine("One or two inputs r string \n so that concatenation of these text box is = " + (a + b));
    Console.ReadKey();
}

static int find(string s)
{
    string s1 = "";
    int f;
    for (int i = 0; i < s.Length; i++)
       for (int j = 0; j <= 9; j++)
       {
           string c = j.ToString();
           if (c[0] == s[i])
           {
               s1 += c[0];
           }
       }

    if (s == s1)
        f = 0;
    else
        f = 1;

    return f;
}

1
สี่ downvote แต่ไม่มีใครพูดทำไม? ฉันเข้าใจว่าเป็นเพราะ TryParse / Parse จะเป็นตัวเลือกที่ดีกว่า แต่ทุกคนที่มาที่นี่จะไม่ทราบ
njplumridge

2
คุณทำให้มันซับซ้อนจนผู้เขียนโปรแกรม C จะพูดว่า "เอ้ยต้องมีวิธีที่ง่ายกว่าในการเขียน"
Ch3shire

1. ไม่มีเหตุผลที่จะอ่านหมายเลขสองจากคอนโซลและเพิ่มเข้าไป ตำแหน่งที่สตริงมาจากนั้นไม่เกี่ยวข้องเลยดังนั้นจึงไม่มีเหตุผลที่จะอ่านอะไรจากคอนโซลเลย
Algoman

2. ตัวแปรสำหรับ f ไม่จำเป็นคุณสามารถคืนค่า 0 หรือ 1 ได้โดยตรง - หากคุณต้องการผลตอบแทนเดี่ยวคุณสามารถใช้ตัวดำเนินการประกอบสำหรับเรื่องนั้นได้ int เป็นชนิดส่งคืนอย่างผิดปกติสำหรับการค้นหาควรเป็นบูลและคุณสามารถส่งคืน s == s1
Algoman

3. คุณคัดลอกตัวเลข s ไปยัง s1 แล้วเปรียบเทียบ s กับ s1 มันช้ากว่าที่ควรจะเป็น ทำไมคุณยังคงวงในต่อไปแม้ว่า c [0] == s [i] เกิดขึ้น? คุณคาดหวังว่า s [i] จะเท่ากับตัวเลขอื่น ๆ ด้วยหรือไม่
Algoman
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.