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
Htmlagilitypack -- Does <Form> Close Itself for Some Reason
Right Aligning Text in PDFpcell
For I = 0, Why Is (I += I++) Equal to 0
Converting File into Base64String and Back Again
Convert Dictionary<String, Object> to Anonymous Object
How to Copy a File to Another Path
Iequalitycomparer<T> That Uses Referenceequals
Map Category Parent Id Self Referencing Table Structure to Ef Core Entity
Put Wpf Control into a Windows Forms Form
Casting List<T> - Covariance/Contravariance Problem
How to Write One to Many Query in Dapper.Net
How to Keep a .Net Console App Running