Sprawdź, czy ciąg jest liczbą

731

Jeśli mam te ciągi:

  1. "abc" = false

  2. "123" = true

  3. "ab2" = false

Czy istnieje polecenie, podobne IsNumeric()lub coś innego, które może zidentyfikować, czy ciąg jest poprawną liczbą?

Złoto
źródło
79
z ich przykładów widać, że mieli na myśli, jeśli cały ciąg reprezentuje liczbę.
Lucas
47
return str.All (Char.IsDigit);
Mohsen
13
str.All (Char.IsDigit) zadeklaruje „3.14” false, a także „-2” i „3E14”. Nie mówiąc już o: „0x10”
Harald Coppoolse,
4
To zależy od typu numeru, który próbujesz sprawdzić. W przypadku liczb całkowitych bez separatora (tj. Ciągów cyfr dziesiętnych) to sprawdzenie działa i jest takie samo jak zaakceptowana odpowiedź i ta sugerowana w OP.
Alex Mazzariol,
1
@Lucas dziękuję za komentarz, nie masz pojęcia, jak długo próbowałem
parsować

Odpowiedzi:

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

Aktualizacja od C # 7:

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

lub jeśli nie potrzebujesz numeru, możesz odrzucić parametr out

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

W var s mogą być zastąpione przez ich rodzajów!

mqp
źródło
126
Chociaż użyłbym double.TryParse, ponieważ chcemy wiedzieć, czy w ogóle reprezentuje liczbę.
John Gietzen
5
Funkcja zwróci true, jeśli przekażę ciąg jako „-123” lub „+123”. Rozumiem, że liczba całkowita ma wartości dodatnie i ujemne. Ale jeśli ten ciąg pochodzi od wpisanego przez użytkownika pola tekstowego, powinien zwrócić wartość false.
user2323308,
9
Jest to dobre rozwiązanie, dopóki użytkownik nie wprowadzi wartości przekraczającej -2 147 483 648 do 2 147 483 647, a potem cicho zawiedzie
BlackTigerX
spróbuj parsować 0,60 (to przecinek!) Jest to niepoprawna liczba, ale zostanie sparsowana jako 60!
Paul Zahra
2
Wolę mieć metodę rozszerzenia dla tego czeku: public static bool IsNumeric(this string text) { double _out; return double.TryParse(text, out _out); }
Hamid Naeemi
350

Zwróci to prawda, jeśli inputwszystkie liczby. Nie wiem, czy jest coś lepszego niż TryParse, ale zadziała.

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

Jeśli chcesz tylko wiedzieć, czy ma jedną lub więcej cyfr pomieszanych ze znakami, odłóż ^ +i $.

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

Edycja: Właściwie myślę, że jest lepszy niż TryParse, ponieważ bardzo długi ciąg może potencjalnie przepełnić TryParse.

John M. Gant
źródło
2
Jednak zbudowanie wyrażenia regularnego raz na zawsze byłoby znacznie bardziej wydajne.
Clément
2
@CFP +1 ... RegEx są zawsze lepsze niż zwykłe funkcje, jeśli mają zastosowanie!
MAXE
19
@MAXE: Nie zgodziłbym się. Kontrole wyrażeń regularnych są dość powolne, więc często istnieją lepsze rozwiązania, jeśli rozważana jest wydajność.
Michał B.,
7
edycja: możesz dodać RegexOptions.Compiledjako parametr, jeśli używasz ich tysiące w celu ewentualnego zwiększenia prędkościRegex.IsMatch(x.BinNumber, @"^\d+$", RegexOptions.Compiled)
Simon_Weaver
9
zawiedzie także na negatywach i rzeczach z.
Noctis
199

Możesz także użyć:

stringTest.All(char.IsDigit);

Będzie to powrót truedo wszystkich numerycznej cyfry (nie float) i falsejeżeli ciąg wejściowy jest każdy rodzaj alfanumerycznych.

Uwaga : stringTestnie powinien być pustym ciągiem, ponieważ przejdzie test numeryczny.

Kunal Goel
źródło
20
To bardzo fajnie. Należy jednak pamiętać: pusty ciąg przejdzie ten test jako numeryczny.
dan-gph
2
@ dan-gph: Cieszę się, że ci się podoba. Tak, masz rację. Zaktualizowałem notatkę powyżej. Dzięki!
Kunal Goel
1
nie działa to również w przypadku miejsc dziesiętnych. Właściwym testem będzie stringTest.All (l => char.IsDigit (l) || '.' == l || '-' == l);
Salman Hasrat Khan
Dzięki za wejście Salman, Aby konkretnie sprawdzić liczbę dziesiętną z ciągu, możesz przejść do opcji - if (Decimal.TryParse (stringTest2, wartość wyjściowa)) {/ * Tak, Dziesiętny /} else {/ Nie, Nie dziesiętny * / }
Kunal Goel
6
Salman, to nie jest takie proste - to byłby ..--..--prawidłowy numer. Najwyraźniej nie.
Flynn1179
133

Użyłem tej funkcji kilka razy:

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

Ale możesz także użyć;

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

Z analizy porównawczej IsNumeric Options

alternatywny tekst
(źródło: aspalliance.com )

alternatywny tekst
(źródło: aspalliance.com )

Nelson Miranda
źródło
80
odwoływanie się do Microsoft.VisualBasic.dll z aplikacji C #? eww: P
Lucas
Nie mam problemu z użyciem „IsNumeric”, działa dobrze. Widać również, że istnieje niewielka różnica skuteczności między TryParse a IsNumeric. Pamiętaj, że TryParse jest nowością w wersji 2.0 i wcześniej lepiej było używać IsNumeric niż jakiejkolwiek innej strategii.
Nelson Miranda
10
Cóż, IsNumeric () VB.NET wewnętrznie używa double.TryParse (), po szeregu ruchów, które są potrzebne (między innymi) do kompatybilności z VB6. Jeśli nie potrzebujesz kompatybilności, double.TryParse () jest równie prosty w użyciu i oszczędza ci marnowania pamięci poprzez ładowanie Microsoft.VisualBasic.dll w procesie.
Euro Micelli
4
Szybka uwaga: użycie wyrażenia regularnego będzie znacznie szybsze, jeśli uda ci się zbudować leżącą u podstaw maszynę skończoną raz na zawsze. Zasadniczo budowanie maszyny stanów zajmuje O (2 ^ n), gdzie n jest długością wyrażenia regularnego, podczas gdy odczyt to O (k), gdzie k jest długością przeszukiwanego ciągu. Więc przebudowywanie wyrażenia regularnego za każdym razem wprowadza błąd.
Clément,
2
@Lucas Właściwie jest tam kilka naprawdę fajnych rzeczy, jak pełny parser csv. Nie ma powodu, aby go nie używać, jeśli istnieje.
Nyerguds
32

Jest to prawdopodobnie najlepsza opcja w języku C #.

Jeśli chcesz wiedzieć, czy ciąg zawiera liczbę całkowitą (liczbę całkowitą):

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

Metoda TryParse spróbuje przekonwertować ciąg na liczbę (liczbę całkowitą), a jeśli się powiedzie, zwróci true i umieści odpowiednią liczbę w myInt. Jeśli nie, zwraca false.

Rozwiązania wykorzystujące int.Parse(someString)alternatywę pokazaną w innych odpowiedziach działają, ale jest znacznie wolniejsze, ponieważ zgłaszanie wyjątków jest bardzo kosztowne. TryParse(...)został dodany do języka C # w wersji 2 i do tego czasu nie miałeś wyboru. Teraz to robisz: dlatego powinieneś unikać Parse()alternatywy.

Jeśli chcesz akceptować liczby dziesiętne, klasa dziesiętna również ma .TryParse(...)metodę. Zamień int na dziesiętny w powyższej dyskusji i obowiązują te same zasady.

Euro Micelli
źródło
Dlaczego TryParse jest lepszy niż porównywanie wszystkich znaków ze znakami liczb całkowitych?
Arjang
25

Zawsze możesz użyć wbudowanych metod TryParse dla wielu typów danych, aby sprawdzić, czy dany ciąg przejdzie.

Przykład.

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

Wynik będzie wtedy = Prawda

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

Wynik wtedy = Fałsz

TheTXI
źródło
Myślę, że mogłem to zrobić bardziej w składni stylu VB niż w C #, ale obowiązują te same zasady.
TheTXI
22

Jeśli nie chcesz używać int.Parse lub double.Parse, możesz rzucić własny za pomocą czegoś takiego:

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;
    }
}
BFree
źródło
7
Co jeśli mieliby na myśli tylko liczby całkowite? Co z lokalizacjami, w których „.” jest separatorem grupy, a nie przecinkiem (np. pt-Br)? co z liczbami ujemnymi? separatory grup (przecinki w języku angielskim)? symbole walutowe? TryParse () może zarządzać nimi wszystkimi zgodnie z wymaganiami za pomocą NumberStyles i IFormatProvider.
Lucas
O tak, bardziej podoba mi się wersja All. Nigdy tak naprawdę nie korzystałem z tej metody rozszerzenia, dobra rozmowa. Chociaż powinna to być s.ToCharArray (). Wszystkie (..). Jeśli chodzi o twój drugi punkt, słyszę cię, dlatego zdecydowałem się na niego, jeśli nie chcesz używać int.Parse .... (który, jak
zakładam,
11
1.3.3.8.5 nie jest tak naprawdę liczbą, podczas gdy 1.23E5 jest.
Clément,
4
logika jest wadliwa. -1
Russel Yang
1
@Lucas Zgadzam się, że TryParse obsługuje więcej, ale czasami nie jest to potrzebne. Muszę tylko zweryfikować pola numerów kart kredytowych (które mogą zawierać tylko cyfry). To rozwiązanie jest prawie zdecydowanie szybsze niż parsowanie.
Millie Smith,
14

Jeśli chcesz wyłapać szersze spektrum liczb, à_numeric PHP , możesz użyć następujących opcji:

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

Test jednostkowy:

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

Pamiętaj, że fakt, że wartość jest liczbą, nie oznacza, że ​​można ją przekonwertować na typ liczbowy. Na przykład "999999999999999999999999999999.9999999999"jest perfekcyjnie prawidłową wartością numeryczną, ale nie pasuje do typu liczbowego .NET (to znaczy nie zdefiniowanego w standardowej bibliotece).

JDB wciąż pamięta Monikę
źródło
Nie próbuje być tutaj inteligentnym alecem, ale wydaje się, że zawodzi w przypadku ciągu „0”. Mój Regex nie istnieje. Czy jest na to prosta poprawka? Dostaję „0” i ewentualnie „0,0”, a nawet „-0,0” jako możliwe prawidłowe wartości liczbowe.
Steve Hibbert
@ SteveHibbert - Wszyscy wiedzą, że „0” nie jest liczbą! Poważnie ... skorygował regex, aby dopasować 0.
JDB wciąż pamięta Monikę
Hmmm, czy to ja, czy „0” nadal nie jest rozpoznawane jako numeryczne?
Steve Hibbert,
1
Będąc leniwym i ignorującym wyrażenia regularne, wyciąłem i wkleiłem powyższy kod, który wygląda, jakby zawierał zmianę typu „0.0”. Przeprowadziłem test, aby sprawdzić, czy ciąg „0” działa .IsNumeric () i czy zwraca false. Myślę, że test ósemkowy zwróci prawdę dla wszystkiego, co ma dwa znaki numeryczne, gdzie pierwszy jest równy zero (a drugi wynosi od zera do siódmej), ale zwróci fałsz dla samego dużego, samotnego zera. Jeśli testujesz „0”, używając powyższego kodu, czy otrzymujesz fałsz? Przepraszam, gdybym wiedział więcej wyrażeń regularnych, byłbym w stanie wyrazić lepszą opinię. Musisz przeczytać.
Steve Hibbert
1
! Doh! Po prostu ponownie przeczytaj swój komentarz powyżej, przegapiłem dodatkową gwiazdkę, zaktualizowałem tylko linię dziesiętną. Mając to na miejscu, masz rację, „0” IsNumeric. Przepraszamy za rozgoryczenie i bardzo dziękuję za aktualizację, mam nadzieję, że pomoże to również innym. Bardzo zobowiązany.
Steve Hibbert
14

Wiem, że to stary wątek, ale żadna z odpowiedzi tak naprawdę mi nie zrobiła - ani nieefektywna, ani nie zamknięta w sobie dla łatwego ponownego użycia. Chciałem również upewnić się, że zwróci wartość false, jeśli ciąg znaków był pusty lub zerowy. TryParse zwraca w tym przypadku wartość true (pusty ciąg nie powoduje błędu podczas analizowania jako liczby). Oto moja metoda rozszerzenia ciągu:

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

Prosty w użyciu:

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

Lub, jeśli chcesz przetestować inne typy liczb, możesz określić „styl”. Aby więc przekonwertować liczbę za pomocą wykładnika, możesz użyć:

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

Lub, aby przetestować potencjalny ciąg szesnastkowy, możesz użyć:

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

Opcjonalnego parametru „kultura” można używać w podobny sposób.

Ogranicza to to, że nie można konwertować ciągów, które są zbyt duże, aby mogły być zawarte w podwójnym, ale jest to ograniczony wymóg i myślę, że jeśli pracujesz z liczbami większymi niż to, prawdopodobnie będziesz potrzebować dodatkowej specjalistycznej obsługi liczb i tak działa.

Cyberpy
źródło
2
Działa świetnie, z tym wyjątkiem, że Double.TryParse nie obsługuje NumberStyles.HexNumber. Zobacz MSDN Double.TryParse. Jakiś powód, dla którego próbujesz TryParse przed sprawdzeniem IsNullOrWhiteSpace? TryParse zwraca wartość false, jeśli IsNullOrWhiteSpace, prawda?
Harald Coppoolse
10

Możesz użyć TryParse, aby ustalić, czy ciąg może zostać przetworzony na liczbę całkowitą.

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

Wartość logiczna powie ci, czy zadziałało, czy nie.

Craig
źródło
9

Jeśli chcesz sprawdzić, czy ciąg jest liczbą (zakładam, że jest to ciąg, ponieważ jeśli jest to liczba, duh, wiesz, że to jeden).

  • Bez wyrażeń regularnych i
  • używając kodu Microsoft w jak największym stopniu

możesz także:

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

Zajmie się to zwykłymi nieprzyjemnościami:

  • Na początku minus (-) lub plus (+)
  • zawiera znak dziesiętnyBigIntegers nie parsuje liczb z przecinkiem dziesiętnym. (Więc: BigInteger.Parse("3.3")wyrzuci wyjątek i TryParsedla tego samego zwróci false)
  • żadnych śmiesznych cyfr
  • obejmuje przypadki, w których liczba jest większa niż zwykłe użycie Double.TryParse

Będziesz musiał dodać odniesienie do klasy System.Numericsi mieć ją using System.Numerics;na szczycie (cóż, chyba druga to bonus :)

Noctis
źródło
8

Myślę, że ta odpowiedź zostanie po prostu zagubiona między wszystkimi innymi, ale tak czy inaczej, proszę bardzo.

Skończyło się na tym pytaniu przez Google, ponieważ chciałem sprawdzić, czy stringbyło numerictak, że mogę po prostu użyć double.Parse("123")zamiast TryParse()metody.

Dlaczego? Ponieważ denerwujące jest zadeklarowanie outzmiennej i sprawdzenie wyniku, TryParse()zanim dowiesz się, czy parsowanie się nie powiodło. Chcę użyć polecenia, ternary operatoraby sprawdzić, czy stringjest, numericala następnie po prostu parsować je w pierwszym wyrażeniu trójskładnikowym lub podać wartość domyślną w drugim wyrażeniu trójskładnikowym.

Lubię to:

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

Jest po prostu o wiele czystszy niż:

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

Zrobiłem parę extension methodsdla tych przypadków:


Metoda rozszerzenia 1

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

Przykład:

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

Ponieważ IsParseableAs()próba przetworzenia łańcucha jako odpowiedniego typu zamiast tylko sprawdzenia, czy łańcuch jest „numeryczny”, powinna być całkiem bezpieczna. I możesz go nawet używać do typów nienumerycznych, które mają taką TryParse()metodę DateTime.

Metoda wykorzystuje refleksję i ostatecznie wywołujesz TryParse()metodę dwukrotnie, co oczywiście nie jest tak wydajne, ale nie wszystko musi być w pełni zoptymalizowane, czasami wygoda jest po prostu ważniejsza.

Tej metody można także użyć do łatwego parsowania listy ciągów liczbowych na listę doublelub inny typ z wartością domyślną bez wychwytywania jakichkolwiek wyjątków:

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

Metoda rozszerzenia dwa

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

Ta metoda rozszerzenia pozwala przeanalizować stringjak każdy, typektóry ma TryParse()metodę, a także pozwala określić wartość domyślną, która ma zostać zwrócona, jeśli konwersja się nie powiedzie.

Jest to lepsze niż użycie operatora trójskładnikowego z powyższą metodą rozszerzenia, ponieważ dokonuje konwersji tylko raz. Nadal jednak używa refleksji ...

Przykłady:

"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);

Wyjścia:

123
25
123,78
107,4
28.10.2014 00:00:00
01.01.0001 00:00:00
Hein Andre Grønnestad
źródło
4
Wierzę, że wymyśliłeś jedno z najbardziej nieefektywnych podejść, jakie do tej pory widziałem. Nie tylko parsujesz łańcuch dwa razy (w przypadku, gdy jest on parsowalny), ale także wywołujesz wielokrotnie funkcje odbicia, aby to zrobić. I na koniec, nawet nie zapisujesz żadnych naciśnięć klawiszy przy użyciu metody rozszerzenia.
JDB wciąż pamięta Monikę
Dziękuję za powtórzenie tego, co sam napisałem w akapicie od drugiego do ostatniego. Również biorąc pod uwagę mój ostatni przykład, zdecydowanie oszczędzasz naciśnięcia klawiszy przy użyciu tej metody rozszerzenia. Ta odpowiedź nie twierdzi, że jest jakimś magicznym rozwiązaniem jakiegokolwiek problemu, jest jedynie przykładem kodu. Użyj go lub nie używaj go. Myślę, że jest to wygodne, gdy jest właściwie stosowane. I zawiera przykłady metod rozszerzenia i refleksji, być może ktoś może się z tego nauczyć.
Hein Andre Grønnestad
5
Próbowałeś var x = double.TryParse("2.2", new double()) ? double.Parse("2.2") : 0.0;?
JDB wciąż pamięta Monikę
2
Tak i to nie działa. Argument 2 must be passed with the 'out' keywordi jeśli określisz outtak dobrze, jak newdostaniesz A ref or out argument must be an assignable variable.
Hein Andre Grønnestad,
1
Wydajność TryParse jest lepsza niż wszystkie dostępne tutaj. Wyniki: TryParse 8 Regex 20 PHP IsNumeric 30 Refleksje TryParse 31 Kod testowy dotnetfiddle.net/x8GjAF
prampe
7

Jeśli chcesz wiedzieć, czy ciąg jest liczbą, zawsze możesz spróbować go parsować:

var numberString = "123";
int number;

int.TryParse(numberString , out number);

Zauważ, że TryParsezwraca a bool, którego możesz użyć do sprawdzenia, czy parsowanie się powiodło.

Gabriel Florit
źródło
7

Double.TryParse

bool Double.TryParse(string s, out double result)

źródło
4

AKTUALIZACJA Kunal Noel Answer

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

Ale w tym przypadku mamy puste łańcuchy, które przejdą ten test, więc możesz:

if (!string.IsNullOrEmpty(stringTest) && stringTest.All(char.IsDigit)){
   // Do your logic here
}
dayanrr91
źródło
4

Najlepsze elastyczne rozwiązanie z wbudowaną funkcją .net o nazwie- char.IsDigit. Działa z nieograniczoną liczbą długich. Zwróci prawdę tylko wtedy, gdy każdy znak jest liczbą. Używałem go wiele razy bez problemów i znacznie łatwiejsze rozwiązanie, jakie kiedykolwiek znalazłem. Zrobiłem przykładową metodę. Jest gotowy do użycia. Ponadto dodałem sprawdzanie poprawności dla pustych i pustych danych wejściowych. Ta metoda jest teraz całkowicie kuloodporna

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;
            }
        }
    }
Liakat
źródło
2

Za pomocą c # 7 można wstawić zmienną out:

if(int.TryParse(str, out int v))
{
}
Chad Kuehn
źródło
2

Skorzystaj z tych metod rozszerzenia, aby wyraźnie rozróżnić między sprawdzaniem, czy łańcuch jest numeryczny i czy łańcuch zawiera tylko 0–9 cyfr

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;
    }
}
userSteve
źródło
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;
}
OMANSAK
źródło
1

Mam nadzieję że to pomoże

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

if isNumber 
{
//string is number
}
else
{
//string is not a number
}
Bieg
źródło
0

Pobierz w swoim projekcie odniesienie do języka Visual Basic i użyj jego metody Information.IsNumeric, takiej jak pokazano poniżej, i możesz przechwytywać liczby zmiennoprzecinkowe, a także liczby całkowite, w przeciwieństwie do powyższej odpowiedzi, która wyłapuje tylko liczby całkowite.

    // Using Microsoft.VisualBasic;

    var txt = "ABCDEFG";

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

IsNumeric("12.3"); // true
IsNumeric("1"); // true
IsNumeric("abc"); // false
ΩmegaMan
źródło
Potencjalnym problemem związanym z tym podejściem jest IsNumericanaliza znaków w łańcuchu. Liczba taka 9999999999999999999999999999999999999999999999999999999999.99999999999zarejestruje się jako True, mimo że nie ma możliwości reprezentowania tej liczby przy użyciu standardowego typu numerycznego.
JDB wciąż pamięta Monikę
0

Wypróbuj poniższe reguły

new Regex(@"^\d{4}").IsMatch("6")    // false
new Regex(@"^\d{4}").IsMatch("68ab") // false
new Regex(@"^\d{4}").IsMatch("1111abcdefg") ```
Tahir
źródło
0

Wszystkie odpowiedzi są przydatne. Ale podczas szukania rozwiązania, w którym wartość liczbowa wynosi 12 cyfr lub więcej (w moim przypadku), a następnie podczas debugowania znalazłem przydatne rozwiązanie:

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

Zmienna wynikowa da ci wartość prawda lub fałsz.

Nayan_07
źródło
-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;
}
Vino
źródło
1
Cztery głosy negatywne, ale nikt nie powiedział dlaczego? Przypuszczam, że to dlatego, że TryParse / Parse byłoby lepszą opcją, ale nie wszyscy, którzy tu przyjdą, będą o tym wiedzieć.
njplumridge
2
Sprawiłeś,
1. Nie ma powodu, aby czytać DWIE liczby z konsoli i dodawać je. To, skąd pochodzi ten ciąg znaków, nie ma znaczenia, więc nie ma powodu, aby w ogóle czytać z konsoli.
Algoman
2. Zmienna dla f jest niepotrzebna, możesz zwrócić 0 lub 1 bezpośrednio - jeśli chcesz pojedynczy zwrot, możesz do tego użyć operatora trójskładnikowego. int jest również niewłaściwym typem zwrotu dla find, powinien być bool i możesz zwrócić s == s1
Algoman
3. kopiujesz cyfry s na s1, a następnie porównujesz s do s1. Jest to o wiele wolniejsze, niż trzeba. Również dlaczego kontynuujesz wewnętrzną pętlę, nawet jeśli zdarzyło się c [0] == s [i]? Czy oczekujesz, że s [i] będzie równy również innym cyfrom?
Algoman