Difference Between Char.Isdigit() and Char.Isnumber() in C#

Difference between Char.IsDigit() and Char.IsNumber() in C#

Char.IsDigit() is a subset of Char.IsNumber().

Some of the characters that are 'numeric' but not digits include 0x00b2 and 0x00b3 which are superscripted 2 and 3 ('²' and '³') and the glyphs that are fractions such as '¼', '½', and '¾'.

Note that there are quite a few characters that IsDigit() returns true for that are not in the ASCII range of 0x30 to 0x39, such as these Thai digit characters: '๐' '๑' '๒' '๓' '๔' '๕' '๖' '๗' '๘' '๙'.

This snippet of code tells you which code points differ:

static private void test()
{
for (int i = 0; i <= 0xffff; ++i)
{
char c = (char) i;

if (Char.IsDigit( c) != Char.IsNumber( c)) {
Console.WriteLine( "Char value {0:x} IsDigit() = {1}, IsNumber() = {2}", i, Char.IsDigit( c), Char.IsNumber( c));
}
}
}

Char.IsDigit() vs Char.IsNumber(), what's the difference?

// 1/2 symbol
Char.IsNumber('½'); // true
Char.IsDigit('½'); // false

// Unicode character for Roman numeral 5 (V)
Char.IsNumber('\x2165'); // true
Char.IsDigit('\x2165'); // false

char.IsNumber()

char.IsNumber() returns true if the character is a number ('0', '1', ... '9').

And e.Handled = true says "this event was already handled, so ignore it".

So your code effectively means this:

if (e.KeyChar is a number)
Ignore this event

Looking at it this way, you probably see why your code only ignores numbers.

So the solution of using !char.IsNumber() is correct, as it basically says "If the character is not a number, ignore this event".

Also, note that you probably are looking for Char.IsDigit, as Char.IsNumber also recognizes other characters as numbers. Char.IsDigit returns true only for '0' to '9', which is most probably what you want.

Substrings and Char.Is/Number Confusion.

Here's a correct way to do it using char.IsLetter and char.IsNumber.

if(myString.Length == 9
&& char.IsLetter(myString[0])
&& char.IsLetter(myString[1])
&& char.IsLetter(myString[2])
&& char.IsNumber(myString[3])
&& char.IsNumber(myString[4])
&& char.IsNumber(myString[5])
&& char.IsLetter(myString[6])
&& char.IsLetter(myString[7])
&& char.IsNumber(myString[8]))
{
// match.
}

Basically you have validate the length of the string, and then validate each character.

You could also use char.IsDigit to limit the match to radix-10 digit versus char.IsNumber that will match any Unicode character that is deemed a number (fractions, subscripts, superscripts, Roman numerals, currency numerators, encircled numbers, and script-specific digits). Also char.IsLetter will also match any Unicode character that is deemed a letter which will stray outside of the basic A-Z. To restrict numbers to 0-9 and letters to A-Z you could do this instead.

public static IsAtoZ(char c)
{
return ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z');
}

if(myString.Length == 9
&& IsAtoZ(myString[0])
&& IsAtoZ(myString[1])
&& IsAtoZ(myString[2])
&& char.IsDigit(myString[3])
&& char.IsDigit(myString[4])
&& char.IsDigit(myString[5])
&& IsAtoZ(myString[6])
&& IsAtoZ(myString[7])
&& char.IsDigit(myString[8]))
{
// match.
}

But honestly at this point a regular expression will be more terse. But note that you'll still have to consider if you want to match Unicode characters and use the correct regular expression based on that.

Identify if a string is a number

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

Update As of C# 7:

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

or if you don't need the number you can discard the out parameter

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

The var s can be replaced by their respective types!

Substrings and Char.Is/Number Confusion.

Here's a correct way to do it using char.IsLetter and char.IsNumber.

if(myString.Length == 9
&& char.IsLetter(myString[0])
&& char.IsLetter(myString[1])
&& char.IsLetter(myString[2])
&& char.IsNumber(myString[3])
&& char.IsNumber(myString[4])
&& char.IsNumber(myString[5])
&& char.IsLetter(myString[6])
&& char.IsLetter(myString[7])
&& char.IsNumber(myString[8]))
{
// match.
}

Basically you have validate the length of the string, and then validate each character.

You could also use char.IsDigit to limit the match to radix-10 digit versus char.IsNumber that will match any Unicode character that is deemed a number (fractions, subscripts, superscripts, Roman numerals, currency numerators, encircled numbers, and script-specific digits). Also char.IsLetter will also match any Unicode character that is deemed a letter which will stray outside of the basic A-Z. To restrict numbers to 0-9 and letters to A-Z you could do this instead.

public static IsAtoZ(char c)
{
return ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z');
}

if(myString.Length == 9
&& IsAtoZ(myString[0])
&& IsAtoZ(myString[1])
&& IsAtoZ(myString[2])
&& char.IsDigit(myString[3])
&& char.IsDigit(myString[4])
&& char.IsDigit(myString[5])
&& IsAtoZ(myString[6])
&& IsAtoZ(myString[7])
&& char.IsDigit(myString[8]))
{
// match.
}

But honestly at this point a regular expression will be more terse. But note that you'll still have to consider if you want to match Unicode characters and use the correct regular expression based on that.

How can I find the numbers in an array of characters?

char.IsDigit

So:

if (Char.IsDigit(example[3]))
{
Console.WriteLine(...);
}

If you want all the chars:

IEnumerable<char> digitList = example.Where(c => Char.IsDigit(c));
//or
char[] digitArray = example.Where(c => Char.IsDigit(c)).ToArray();

Use Char.IsNumber if you want all the extra "numbers" in Unicode, specifically:

Numbers include characters such as fractions, subscripts,
superscripts, Roman numerals, currency numerators, encircled numbers,
and script-specific digits.

Substrings and Char.Is/Number Confusion.

Here's a correct way to do it using char.IsLetter and char.IsNumber.

if(myString.Length == 9
&& char.IsLetter(myString[0])
&& char.IsLetter(myString[1])
&& char.IsLetter(myString[2])
&& char.IsNumber(myString[3])
&& char.IsNumber(myString[4])
&& char.IsNumber(myString[5])
&& char.IsLetter(myString[6])
&& char.IsLetter(myString[7])
&& char.IsNumber(myString[8]))
{
// match.
}

Basically you have validate the length of the string, and then validate each character.

You could also use char.IsDigit to limit the match to radix-10 digit versus char.IsNumber that will match any Unicode character that is deemed a number (fractions, subscripts, superscripts, Roman numerals, currency numerators, encircled numbers, and script-specific digits). Also char.IsLetter will also match any Unicode character that is deemed a letter which will stray outside of the basic A-Z. To restrict numbers to 0-9 and letters to A-Z you could do this instead.

public static IsAtoZ(char c)
{
return ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z');
}

if(myString.Length == 9
&& IsAtoZ(myString[0])
&& IsAtoZ(myString[1])
&& IsAtoZ(myString[2])
&& char.IsDigit(myString[3])
&& char.IsDigit(myString[4])
&& char.IsDigit(myString[5])
&& IsAtoZ(myString[6])
&& IsAtoZ(myString[7])
&& char.IsDigit(myString[8]))
{
// match.
}

But honestly at this point a regular expression will be more terse. But note that you'll still have to consider if you want to match Unicode characters and use the correct regular expression based on that.



Related Topics



Leave a reply



Submit