229

I know a few ways of how to check if a string contains only digits:
RegEx, int.parse, tryparse, looping, etc.

Can anyone tell me what the fastest way to check is?

I need only to CHECK the value, no need to actually parse it.

By "digit" I mean specifically ASCII digits: 0 1 2 3 4 5 6 7 8 9.

This is not the same question as Identify if a string is a number, since this question is not only about how to identify, but also about what the fastest method for doing so is.

zcoop98
  • 2,590
  • 1
  • 18
  • 31
Nahum
  • 6,959
  • 12
  • 48
  • 69

21 Answers21

329
bool IsDigitsOnly(string str)
{
    foreach (char c in str)
    {
        if (c < '0' || c > '9')
            return false;
    }

    return true;
}

Will probably be the fastest way to do it.

jakobbotsch
  • 6,167
  • 4
  • 26
  • 39
  • I'd say so too. You have to check each character obviously, and I can't think of a faster way of checking a single character for being a digit other than that, being simple comparisons. –  Sep 18 '11 at 15:13
  • 23
    There's also `char.IsDigit()` – Keith Feb 05 '13 at 08:14
  • @Keith Which accepts far more characters than the above code since it supports unicode, but simply comparing with `'0'` to `'9'` only accepts ASCII digits. – CodesInChaos Sep 17 '13 at 16:57
  • @CodesInChaos `char.IsDigit()` does support unicode, as does the `char` code above and both return `true` for the same radix-10 digits. I think you're thinking of `char.IsNumber()`, which will return true for fraction symbols and the like. – Keith Sep 18 '13 at 09:04
  • 36
    @Keith `IsDigit` returns `true` for about three-hundred more characters. Including full width decimal digits `0123`... (common in China and Japan) and digits from other cultures e.g. `০১২௧௨௩௪꘤꘥꘦꘧꘨` and plenty more. – CodesInChaos Sep 18 '13 at 09:08
  • @CodesInChaos, ah, I see what you mean. – Keith Sep 18 '13 at 12:59
  • 80
    if anyone cares, this can certainly be reduced to a one-liner -> `return str.All(c => c >= '0' && c <= '9');` – Jonesopolis Feb 06 '14 at 14:07
  • 22
    You could simply do this too: `return str.All(char.IsDigit);`. Hooray for method groups! – Icemanind Aug 27 '14 at 18:10
  • 1
    As people have pointed out, this gives the incorrect answer, with e.g. returning `false` for `"123൨൩൪٢٣٤٥٦३४५"` when it should return `true`, you could also get a bit of a performance improvement by not using a lambda; not worth it most of the time but the question is "fastest way". – Jon Hanna Dec 03 '14 at 23:54
  • 11
    Please note that empty string isn't a vaild number. – Danon Mar 14 '15 at 21:29
  • 2
    How about dot and comma? – akd Aug 18 '15 at 09:39
  • @Jonesopolis, I believe comparing characters are faster than using Linq libraries (as OP asked). you can compare the speed using test method in TheCodeKing's answer – AaA Oct 23 '15 at 06:42
  • @akd, OP asked for Digits only, if you need comma and dot, you need to add them yourself or use IsNumber method suggested in comments. – AaA Oct 23 '15 at 06:47
  • Using `for` instead of `foreach` will speed it up even more. – jazzcat Jan 28 '16 at 13:08
  • @jazzcat No it won't. The code generated for the `foreach` and `for` versions are exactly the same. – jakobbotsch Jan 28 '16 at 21:26
  • 1
    I ended up with `str != "" && str.All(c => c >= '0' && c <= '9')`. An empty string leads to a `FormatException` when parsing – DerpyNerd Aug 13 '16 at 11:45
  • @digEmAll, that is your opinion. What are the relevant facts? Do you know what the relevant code is that is generated for a release build? – Sam Hobbs Apr 24 '17 at 07:25
  • @user34660: Well, another answer posted a benchmark saying that this is the fastest approach. It has some limitations, as the fact which does not handle all unicode numbers (e.g. numbers like "൪٢٣٤٥٦३४५") and the empty string corner-case returns true... but if you just need to check if all the string contains only "0123456789" this is probably the fastest approach in C# since it has just a foreach loop (maybe you can even speed up a little with a for-loop) and an if statement with two comparisons... – digEmAll Apr 24 '17 at 17:31
  • I don't know if " 123" passes for an integer. hmm. I think it would pass the int.Parse(...) test. I don't think it would pass the c>='0' && c <= '9'. It's all about the definition. stay out of trouble you crazy mathematicians! – LongChalk Aug 15 '18 at 13:16
  • 1
    Due to lazy evaluation of the two conditions it can be faster to check if c <= '9' first, depending on the other chars you can have. Statistically there are more ASCII chars after '9' than before '0'. – Alsatian May 16 '19 at 15:52
  • 1
    Nice, I just made this a string extension for checking DUNS number formatting – KeithL Nov 15 '19 at 18:23
122

You could do this simply using LINQ:

return str.All(char.IsDigit);

  1. .All returns true for empty strings and throws an exception for null strings.
  2. char.IsDigit is true for all Unicode digit characters.
zcoop98
  • 2,590
  • 1
  • 18
  • 31
Uday
  • 1,398
  • 1
  • 12
  • 21
  • 7
    char.IsDigit matches numerous unicode digits from various locales (see http://www.fileformat.info/info/unicode/category/Nd/list.htm). Also, your answer uses LINQ so it unlikely to be the *fastest* way to do it. It might be sufficient for most usecases though. – Stephen Holt Sep 12 '18 at 11:55
  • 1
    @StephenHolt Yes you are right, I realize that is not necessarily the fastest, but it's probably the easiest to write. – Uday Sep 13 '18 at 05:09
  • Yep, fair point. I also wrote a similar answer (see below) a few years ago, although my version just tested if the char was between '0' and '9' to eliminate chars from other locales. That will depend on the exact requirements. – Stephen Holt Sep 18 '18 at 09:29
81

Here's some benchmarks based on 1000000 parses of the same string:

Updated for release stats:

IsDigitsOnly: 384588
TryParse:     639583
Regex:        1329571

Here's the code, looks like IsDigitsOnly is faster:

class Program
{
    private static Regex regex = new Regex("^[0-9]+$", RegexOptions.Compiled);

    static void Main(string[] args)
    {
        Stopwatch watch = new Stopwatch();
        string test = int.MaxValue.ToString();
        int value;

        watch.Start();
        for(int i=0; i< 1000000; i++)
        {
            int.TryParse(test, out value);
        }
        watch.Stop();
        Console.WriteLine("TryParse: "+watch.ElapsedTicks);

        watch.Reset();
        watch.Start();
        for (int i = 0; i < 1000000; i++)
        {
            IsDigitsOnly(test);
        }
        watch.Stop();
        Console.WriteLine("IsDigitsOnly: " + watch.ElapsedTicks);

        watch.Reset();
        watch.Start();
        for (int i = 0; i < 1000000; i++)
        {
            regex.IsMatch(test);
        }
        watch.Stop();
        Console.WriteLine("Regex: " + watch.ElapsedTicks);

        Console.ReadLine();
    }

    static bool IsDigitsOnly(string str)
    {
        foreach (char c in str)
        {
            if (c < '0' || c > '9')
                return false;
        }

        return true;
    }
}

Of course it's worth noting that TryParse does allow leading/trailing whitespace as well as culture specific symbols. It's also limited on length of string.

TheCodeKing
  • 19,064
  • 3
  • 47
  • 70
  • Parsing a number definitely takes more time than just checking each digit, as you're performing base conversion. –  Sep 18 '11 at 11:21
  • 2
    1000 parses of the same string should take almost *no* time at all, by the way, well under the time where natural noise renders the results insignificant. I'd expect to have to parse it a *million* times to get useful timings. – Jon Skeet Sep 18 '11 at 11:46
  • Downvoted because the benchmark is *way* too short to be useful *and* you didn't spot that your method is giving the wrong answer even for the sample you're testing. The sample string *is* composed only of digits, but because it's too long for an `int`, TryParse is returning false. – Jon Skeet Sep 18 '11 at 11:51
  • It's a lot closer with 1m. Ah good point about the length, I missed that. – TheCodeKing Sep 18 '11 at 11:55
  • @TheCodeKing: Try giving it a value where they give the same results - such as `int.MaxValue.ToString()`. On my machine, IsDigitsOnly is then 5 times faster than TryParse. – Jon Skeet Sep 18 '11 at 11:55
  • Ah, I'd missed the "a" in the sample input string. So in this particular case, int.TryParse rejects it faster. Try it with valid values though - and also explain how it's worth being faster if inaccurate (long strings of digits outside the range of int). – Jon Skeet Sep 18 '11 at 11:57
  • Actually, on my box even the sample input you've given is faster using IsDigitsOnly - only be a factor of ~2.5, but definitely faster... – Jon Skeet Sep 18 '11 at 11:58
  • Good call, IsDigitsOnly is now quicker. – TheCodeKing Sep 18 '11 at 11:58
  • 3
    Ooh, with /o+ on compilation, it's now over 5 times faster than int.TryParse. Just to check, you're not running in the debugger are you? – Jon Skeet Sep 18 '11 at 12:13
  • Damn you and your thoughtfulness, I'll update stats. Serves me right for rushing. – TheCodeKing Sep 18 '11 at 12:15
  • TryParse won't work in some situations. What happens if the string is a credit card number with 16 digits. Also when doing benchmarking you should never do them in debug mode. There can be huge differences between running a app in debug mode compared to release mode. – ashlar64 Jan 06 '16 at 17:07
  • not sure if it will effect the results in this case but for accurate benchmarking you should first call the target method several times outside of your timing loop to eliminate any type loading overhead, ideally you would perform enough iterations to remove any JIT compilation overhead as well. – chillitom Jan 28 '16 at 09:43
  • I wanted to test for instead of foreach so I took the program and modified it slightly, it's always slightly slower (in my case anyway): TryParse: 19341651ticks (1934ms). IsDigitsOnlyForeach: 9544898ticks (954ms). IsDigitsOnlyFor: 12040270ticks (1204ms). Regex: 33139980ticks (3313ms). – Issung Nov 06 '19 at 10:04
  • I'm getting the following results on my system: `tryParse: 26 IsAllDigits: 88 Regex: 312` The values are in milliseconds. By these results, tryParse seems to be faster! let me know if I'm getting it wrong. – Praveen Nov 21 '19 at 18:13
35

The char already has an IsDigit(char c) which does this:

 public static bool IsDigit(char c)
    {
      if (!char.IsLatin1(c))
        return CharUnicodeInfo.GetUnicodeCategory(c) == UnicodeCategory.DecimalDigitNumber;
      if ((int) c >= 48)
        return (int) c <= 57;
      else
        return false;
    }

You can simply do this:

var theString = "839278";
bool digitsOnly = theString.All(char.IsDigit);
Sudhanshu Mishra
  • 6,523
  • 2
  • 59
  • 76
flayn
  • 5,272
  • 4
  • 48
  • 69
32

Can be about 20% faster by using just one comparison per char and for instead of foreach:

bool isDigits(string s) 
{ 
    if (s == null || s == "") return false; 

    for (int i = 0; i < s.Length; i++) 
        if ((s[i] ^ '0') > 9) 
            return false; 

    return true; 
}

Code used for testing (always profile because the results depend on hardware, versions, order, etc.):

static bool isDigitsFr(string s) { if (s == null || s == "") return false; for (int i = 0; i < s.Length; i++) if (s[i] < '0' || s[i] > '9') return false; return true; }
static bool isDigitsFu(string s) { if (s == null || s == "") return false; for (int i = 0; i < s.Length; i++) if ((uint)(s[i] - '0') > 9) return false; return true; }
static bool isDigitsFx(string s) { if (s == null || s == "") return false; for (int i = 0; i < s.Length; i++) if ((s[i] ^ '0') > 9) return false; return true; }
static bool isDigitsEr(string s) { if (s == null || s == "") return false; foreach (char c in s) if (c < '0' || c > '9') return false; return true; }
static bool isDigitsEu(string s) { if (s == null || s == "") return false; foreach (char c in s) if ((uint)(c - '0') > 9) return false; return true; }
static bool isDigitsEx(string s) { if (s == null || s == "") return false; foreach (char c in s) if ((c ^ '0') > 9) return false; return true; }
static void test()
{
    var w = new Stopwatch(); bool b; var s = int.MaxValue + ""; int r = 12345678*2; var ss = new SortedSet<string>(); //s = string.Concat(Enumerable.Range(0, 127).Select(i => ((char)i ^ '0') < 10 ? 1 : 0));
    w.Restart(); for (int i = 0; i < r; i++) b = s.All(char.IsDigit); w.Stop(); ss.Add(w.Elapsed + ".All .IsDigit"); 
    w.Restart(); for (int i = 0; i < r; i++) b = s.All(c => c >= '0' && c <= '9'); w.Stop(); ss.Add(w.Elapsed + ".All <>"); 
    w.Restart(); for (int i = 0; i < r; i++) b = s.All(c => (c ^ '0') < 10); w.Stop(); ss.Add(w.Elapsed + " .All ^"); 
    w.Restart(); for (int i = 0; i < r; i++) b = isDigitsFr(s); w.Stop(); ss.Add(w.Elapsed + " for     <>");
    w.Restart(); for (int i = 0; i < r; i++) b = isDigitsFu(s); w.Stop(); ss.Add(w.Elapsed + " for     -");
    w.Restart(); for (int i = 0; i < r; i++) b = isDigitsFx(s); w.Stop(); ss.Add(w.Elapsed + " for     ^");
    w.Restart(); for (int i = 0; i < r; i++) b = isDigitsEr(s); w.Stop(); ss.Add(w.Elapsed + " foreach <>");
    w.Restart(); for (int i = 0; i < r; i++) b = isDigitsEu(s); w.Stop(); ss.Add(w.Elapsed + " foreach -");
    w.Restart(); for (int i = 0; i < r; i++) b = isDigitsEx(s); w.Stop(); ss.Add(w.Elapsed + " foreach ^");
    MessageBox.Show(string.Join("\n", ss)); return;
}

Results on Intel i5-3470 @ 3.2GHz, VS 2015 .NET 4.6.1 Release mode and optimizations enabled:

time    method          ratio
0.7776  for     ^       1.0000 
0.7984  foreach -       1.0268 
0.8066  foreach ^       1.0372 
0.8940  for     -       1.1497 
0.8976  for     <>      1.1543 
0.9456  foreach <>      1.2160 
4.4559  .All <>         5.7303 
4.7791  .All ^          6.1458 
4.8539  .All. IsDigit   6.2421 

For anyone tempted to use the shorter methods, note that

Slai
  • 22,144
  • 5
  • 45
  • 53
16

If you are concerned about performance, use neither int.TryParse nor Regex - write your own (simple) function (DigitsOnly or DigitsOnly2 below, but not DigitsOnly3 - LINQ seems to incur a significant overhead).

Also, be aware that int.TryParse will fail if the string is too long to "fit" into int.

This simple benchmark...

class Program {

    static bool DigitsOnly(string s) {
        int len = s.Length;
        for (int i = 0; i < len; ++i) {
            char c = s[i];
            if (c < '0' || c > '9')
                return false;
        }
        return true;
    }

    static bool DigitsOnly2(string s) {
        foreach (char c in s) {
            if (c < '0' || c > '9')
                return false;
        }
        return true;
    }

    static bool DigitsOnly3(string s) {
        return s.All(c => c >= '0' && c <= '9');
    }

    static void Main(string[] args) {

        const string s1 = "916734184";
        const string s2 = "916734a84";

        const int iterations = 1000000;
        var sw = new Stopwatch();

        sw.Restart();
        for (int i = 0 ; i < iterations; ++i) {
            bool success = DigitsOnly(s1);
            bool failure = DigitsOnly(s2);
        }
        sw.Stop();
        Console.WriteLine(string.Format("DigitsOnly: {0}", sw.Elapsed));

        sw.Restart();
        for (int i = 0; i < iterations; ++i) {
            bool success = DigitsOnly2(s1);
            bool failure = DigitsOnly2(s2);
        }
        sw.Stop();
        Console.WriteLine(string.Format("DigitsOnly2: {0}", sw.Elapsed));

        sw.Restart();
        for (int i = 0; i < iterations; ++i) {
            bool success = DigitsOnly3(s1);
            bool failure = DigitsOnly3(s2);
        }
        sw.Stop();
        Console.WriteLine(string.Format("DigitsOnly3: {0}", sw.Elapsed));

        sw.Restart();
        for (int i = 0; i < iterations; ++i) {
            int dummy;
            bool success = int.TryParse(s1, out dummy);
            bool failure = int.TryParse(s2, out dummy);
        }
        sw.Stop();
        Console.WriteLine(string.Format("int.TryParse: {0}", sw.Elapsed));

        sw.Restart();
        var regex = new Regex("^[0-9]+$", RegexOptions.Compiled);
        for (int i = 0; i < iterations; ++i) {
            bool success = regex.IsMatch(s1);
            bool failure = regex.IsMatch(s2);
        }
        sw.Stop();
        Console.WriteLine(string.Format("Regex.IsMatch: {0}", sw.Elapsed));

    }

}

...produces the following result...

DigitsOnly: 00:00:00.0346094
DigitsOnly2: 00:00:00.0365220
DigitsOnly3: 00:00:00.2669425
int.TryParse: 00:00:00.3405548
Regex.IsMatch: 00:00:00.7017648
Branko Dimitrijevic
  • 50,809
  • 10
  • 93
  • 167
15

Function with empty validation:

public static bool IsDigitsOnly(string str)
  {             
        return !string.IsNullOrEmpty(str) && str.All(char.IsDigit);
  }
i31nGo
  • 1,422
  • 15
  • 11
12

I like Linq and to make it exit on first mismatch you can do this

string str = '0129834X33';
bool isAllDigits = !str.Any( ch=> ch < '0' || ch > '9' );
Alobidat
  • 462
  • 7
  • 16
11

if it is a single string :

if (str.All(Char.IsDigit))
{
  // string contains only digits
}

if it is a list of strings :

if (lstStr.All(s => s.All(Char.IsDigit)))
{
  // List of strings contains only digits
}
Ah Sa Fa
  • 171
  • 1
  • 10
8

You can do this in a one line LINQ statement. OK, I realise this is not necessarily the fastest, so doesn't technically answer the question, but it's probably the easiest to write:

str.All(c => c >= '0' && c <= '9')
Stephen Holt
  • 2,360
  • 4
  • 26
  • 34
  • 4
    `str.All(char.IsDigit)` is even easier to write, but of course not equivalent to your code. – CodesInChaos Sep 17 '13 at 17:01
  • I tried to test this: http://pastebin.com/PuWBp9n1 on release no debugger of course... and it seems WAYYYY faster. @Jon Skeet can you provide some insight? str.All(c => c >= '0' && c <= '9') seems WAY faster than IsDigit – Nahum Sep 18 '13 at 06:19
  • 1
    @NahumLitvin `IsDigit` supports unicode. So depending on which time-memory trade-offs Microsoft chose when implementing it, the check might be quite expensive. I assume that it forwards to native code, that transition can be quite expensive as well. – CodesInChaos Sep 18 '13 at 09:15
  • @CodesInChaos when you said it was "not equivalent to my code" I went to check what else might match, and it turns out that digits in other locales (e.g. Arabic) would match in your version. I guess it is something that OP would need to consider, whether such digits are valid or not. When doing int.TryParse, I think that would not accept strings containing such characters. – Stephen Holt Sep 19 '13 at 14:26
  • LINQ is the slowest way to accomplish anything. If you want to apply a blanket rule to coding, assume the more high level & functionality something offers, the slower it is. – TravisO Apr 03 '17 at 15:56
  • @TravisO Very true, but in the vast majority of cases on modern machines the speed gained by optimising an expression like the one above is completely negligible. You might even find the system optimises it behind the scenes (I'n not sure on that point). I use LINQ iff it improves clarity in reading the code, and rarely worry if it's efficient or not. – Stephen Holt Apr 30 '17 at 21:33
8

Probably the fastest way is:

myString.All(c => char.IsDigit(c))

Note: it will return True in case your string is empty which is incorrect (if you not considering empty as valid number/digit )

Atulya
  • 153
  • 1
  • 11
7

This should work:

Regex.IsMatch("124", "^[0-9]+$", RegexOptions.Compiled)

int.Parse or int.TryParse won't always work, because the string might contain more digits that an int can hold.

If you are going to do this check more than once it is useful to use a compiled regex - it takes more time the first time, but is much faster after that.

Petar Ivanov
  • 91,536
  • 11
  • 82
  • 95
  • 3
    this is wrong, it returns true if theres even one digit. though the complied idea is awesome. – Nahum Sep 18 '11 at 11:34
  • 1
    This is by far the slowest method, but is the best solution based on unknown size of string. As mentioned the regex also needs a tweak. – TheCodeKing Sep 18 '11 at 11:37
5

This might be coming super late!, but I'm sure it will help someone, as it helped me.

        private static bool IsDigitsOnly(string str)
        {
            return str.All(c => c >= '0' && c <= '9');
        }
user8107351
  • 367
  • 4
  • 20
3

You can try using Regular Expressions by testing the input string to have only digits (0-9) by using the .IsMatch(string input, string pattern) method in C#.

using System;
using System.Text.RegularExpression;

public namespace MyNS
{
    public class MyClass
    {
        public void static Main(string[] args)
        {
             string input = Console.ReadLine();
             bool containsNumber = ContainsOnlyDigits(input);
        }

        private bool ContainOnlyDigits (string input)
        {
            bool containsNumbers = true;
            if (!Regex.IsMatch(input, @"/d"))
            {
                containsNumbers = false;
            }
            return containsNumbers;
        }
    }
}

Regards

Jason Cidras
  • 509
  • 5
  • 11
  • 3
    Hi jason and welcome to Stackoverflow. Thank you for answering but notice that the question was about the fastest way. Regular expressions are relatively slow this was discussed in other answers. – Nahum Apr 25 '14 at 05:35
1

this will work perfectly, there is many other ways but this would work

bool IsDigitsOnly(string str)
    {
        if (str.Length > 0)//if contains characters
        {
            foreach (char c in str)//assign character to c
            {
                if (c < '0' || c > '9')//check if its outside digit range
                    return false;
            }
        }else//empty string
        {
            return false;//empty string 
        }

        return true;//only digits
    }
0

Another approach!

string str = "12345";
bool containsOnlyDigits = true;
try { if(Convert.ToInt32(str) < 0){ containsOnlyDigits = false; } }
catch { containsOnlyDigits = false; }

Here, if the statement Convert.ToInt32(str) fails, then string does not contain digits only. Another possibility is that if the string has "-12345" which gets converted to -12345 successfully, then there is a check for verifying that the number converted is not less than zero.

Ali Sajjad
  • 3,589
  • 1
  • 28
  • 38
  • If all the characters must be digits and cannot lead with the - sign then this would not work. If you aren't concerned with leading or trailing spaces and your string was short enough, you could try either Convert.ToUInt32 or UInt32.tryparse but this wouldn't work for long enough strings. – Brian Edwards Dec 11 '20 at 17:22
  • This will fail for a valid number string that does not fit in "int32" – Syed Irfan Ahmad Jul 10 '22 at 14:35
0

I did small changes @TheCodeKing's answer.

It seems that ;

for int type fastest way is TryParse

for long type fastest way is Regex.

My results below (ticks)

For int:

TryParse Max: 355788
IsDigitsOnly Max: 787013
Regex Max: 1297691

TryParse Avg: 186007
IsDigitsOnly Avg: 430963
Regex Avg: 464657,79

TryParse Min: 162742
IsDigitsOnly Min: 335646
Regex Min: 452121


For float :

TryParse Max : 3151995
IsDigitsOnly Max: 1392740
Regex Max : 1283451

TryParse Avg: 1391636
IsDigitsOnly Avg: 824029
Regex Avg: 501176

TryParse Min: 1187410
IsDigitsOnly Min: 706646
Regex Min: 476204

Code for long:

using System.Diagnostics;
using System.Text.RegularExpressions;

class Program
{
    private static Regex regex = new Regex("^[0-9]+$", RegexOptions.Compiled);

    static void Main(string[] args)
    {
        Stopwatch watch = new Stopwatch();
        watch.Start();
        watch.Stop();
        watch.Reset();
        List<TimeSpan> tryparse = new List<TimeSpan>();
        List<TimeSpan> isdigitsonly = new List<TimeSpan>();
        List<TimeSpan> regexss = new List<TimeSpan>();

        for (int say = 0; say < 1000; say++)
        { 
            float value;

            string test = Random.Shared.NextInt64(1000,long.MaxValue).ToString();
            watch.Start();
            for (int i = 0; i < 1000000; i++)
            {
                float.TryParse(test, out value);
            }
            watch.Stop();
            //Console.WriteLine("TryParse: " + watch.Elapsed);
            tryparse.Add(watch.Elapsed);

            watch.Reset();
            watch.Start();
            for (int i = 0; i < 1000000; i++)
            {
                IsDigitsOnly(test);
            }
            watch.Stop();
            //Console.WriteLine("IsDigitsOnly: " + watch.Elapsed);
            isdigitsonly.Add(watch.Elapsed);
            watch.Reset();
            watch.Start();
            for (int i = 0; i < 1000000; i++)
            {
                regex.IsMatch(test);
            }
            watch.Stop();
            regexss.Add(watch.Elapsed);
            watch.Reset();
            //   Console.WriteLine("Regex: " + watch.Elapsed);
     
            Console.Write("---------------------% " + (Convert.ToDecimal( say)/ 999 * 100).ToString("N2") + "---------------------------");
            Console.CursorLeft = 0;
        }
        Console.WriteLine();
        Console.WriteLine($"TryParse: {tryparse.Max(t => t.Ticks)}");
        Console.WriteLine($"IsDigitsOnly: {isdigitsonly.Max(t => t.Ticks)}");
        Console.WriteLine($"Regex: {regexss.Max(t => t.Ticks)}");
        Console.WriteLine();

        Console.WriteLine($"TryParse Avg: {tryparse.Average(t => t.Ticks)}");
        Console.WriteLine($"IsDigitsOnly Avg: {isdigitsonly.Average(t => t.Ticks)}");
        Console.WriteLine($"Regex Avg: {regexss.Average(t => t.Ticks)}");
        Console.WriteLine();
        Console.WriteLine($"TryParse Min: {tryparse.Min(t => t.Ticks)}");
        Console.WriteLine($"IsDigitsOnly Min: {isdigitsonly.Min(t => t.Ticks)}");
        Console.WriteLine($"Regex Min: {regexss.Min(t => t.Ticks)}");
        Console.ReadLine();
    }

    static bool IsDigitsOnly(string str)
    {
        foreach (char c in str)
        {
            if (c < '0' || c > '9')
                return false;
        }

        return true;
    }
}
-1

Try this code:

bool isDigitsOnly(string str)
{
   try
   {
      int number = Convert.ToInt32(str);
      return true;
   }
   catch (Exception)
   {
      return false;
   }
}
  • Can you explain why your solution is better than the ones already provided? – Noel Widmer Jun 03 '17 at 13:49
  • Because the time order of running this code [o(1)] is less than others [o(n)] – H. Borsipour Jun 06 '17 at 04:00
  • I would be very surprised if `Convert.ToInt32` would run faster than o(n). Do you have any evidence to support this assumption? – BDL Jun 30 '17 at 12:11
  • 1
    it might be faster if str is actually a number, but it would probably be slower in case of Exeption. Also it's not answering the question because it won't work if str is number bigger than int.MaxValue. – Tomer Wolberg Feb 18 '18 at 20:07
-3

What about char.IsDigit(myChar)?

Undo
  • 25,519
  • 37
  • 106
  • 129
Mirko
  • 1
-3

Very Clever and easy way to detect your string is contains only digits or not is this way:

string s = "12fg";

if(s.All(char.IsDigit))
{
   return true; // contains only digits
}
else
{
   return false; // contains not only digits
}
Avtandil Kavrelishvili
  • 1,651
  • 3
  • 27
  • 37
  • The if condition is unnecessary, so is two return statements, you can just return the s.All... But there are other issues such as with empty strings. – alvarlagerlof May 12 '20 at 22:57
-3
public bool CheckforDigits(string x)
{    
    int tr;  
    return x.All(r=> int.TryParse(r.ToString(), out tr));
}
JJJ
  • 32,902
  • 20
  • 89
  • 102
ReR
  • 1
  • Although this code might solve the problem, you should add an explanation why/how it works. And please explain why you think that this code is better than the ones already provided. – BDL Jun 30 '17 at 12:04
  • 1
    In addition: Your code returns True for empty strings. – BDL Jun 30 '17 at 12:18
  • This will fail for a valid number string that does not fit in "int32" – Syed Irfan Ahmad Jul 10 '22 at 14:38