{"id":40333,"date":"2004-03-09T07:00:00","date_gmt":"2004-03-09T07:00:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/2004\/03\/09\/char-isdigit-matches-more-than-just-0-through-9\/"},"modified":"2022-06-30T10:19:54","modified_gmt":"2022-06-30T17:19:54","slug":"char-isdigit-matches-more-than-just-0-through-9","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20040309-00\/?p=40333","title":{"rendered":"Char.IsDigit() matches more than just &quot;0&quot; through &quot;9&quot;"},"content":{"rendered":"<p>Warning: .NET content ahead!<\/p>\n<p>Yesterday, Brad Abrams noted that Char.IsLetter() matches more than just &#8220;A&#8221; through &#8220;Z&#8221;.<\/p>\n<p>What people might not realize is that <a href=\"http:\/\/msdn.microsoft.com\/library\/en-us\/cpref\/html\/frlrfSystemCharClassIsDigitTopic.asp\">Char.IsDigit()<\/a> matches more than just &#8220;0&#8221; through &#8220;9&#8221;.<\/p>\n<blockquote class=\"q\"><p>Valid digits are members of the following category in <a href=\"http:\/\/msdn.microsoft.com\/library\/en-us\/cpref\/html\/frlrfsystemglobalizationunicodecategoryclasstopic.asp\"> UnicodeCategory<\/a>: <b>DecimalDigitNumber<\/b>.<\/p><\/blockquote>\n<p>But what exactly is a <b>DecimalDigitNumber<\/b>?<\/p>\n<blockquote class=\"q\">\n<dl>\n<dt>DecimalDigitNumber<\/dt>\n<dd>Indicates that the character is a decimal digit; that is, in the range 0 through 9. Signified by the Unicode designation &#8220;Nd&#8221; (number, decimal digit). The value is 8.<\/dd>\n<\/dl>\n<\/blockquote>\n<p>At this point you have to go to the <a href=\"http:\/\/www.unicode.org\/\">Unicode Standard Committee<\/a> to see exactly what qualifies as &#8220;Nd&#8221;, and then you get lost in a twisty maze of specifications and documents, all different.<\/p>\n<p>So let&#8217;s run an experiment.<\/p>\n<pre>class Program {\r\n  public static void Main(string[] args) {\r\n    System.Console.WriteLine(\r\n      System.Text.RegularExpressions.Regex.Match(\r\n        \"\\x0661\\x0662\\x0663\", \/\/ \"<span style=\"font-size: xx-small;\">\u0661\u0662\u0663<\/span>\"\r\n        \"^\\\\d+$\").Success);\r\n    System.Console.WriteLine(\r\n      System.Char.IsDigit('\\x0661'));\r\n  }\r\n}\r\n<\/pre>\n<p>The characters in the string are Arabic digits, but they are still digits, as evidenced by the program output:<\/p>\n<pre>True\r\nTrue\r\n<\/pre>\n<p>Uh-oh. <a href=\"http:\/\/aspzone.com\/articles\/173.aspx\"> Do you have this bug in your parameter validation?<\/a> (<a href=\"http:\/\/samples.gotdotnet.com\/quickstart\/howto\/doc\/regexcommon.aspx\">More examples.<\/a>.) If you use a pattern like <code>@\"^\\d$\"<\/code> to validate that you receive only digits, and then later use <code>System.Int32.Parse()<\/code> to parse it, then I can hand you some Arabic digits and sit back and watch the fireworks. The Arabic digits will pass your validation expression, but when you get around to using it, boom, you throw a <code>System.FormatException<\/code> and die.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Warning: .NET content ahead! Yesterday, Brad Abrams noted that Char.IsLetter() matches more than just &#8220;A&#8221; through &#8220;Z&#8221;. What people might not realize is that Char.IsDigit() matches more than just &#8220;0&#8221; through &#8220;9&#8221;. Valid digits are members of the following category in UnicodeCategory: DecimalDigitNumber. But what exactly is a DecimalDigitNumber? DecimalDigitNumber Indicates that the character is [&hellip;]<\/p>\n","protected":false},"author":1069,"featured_media":111744,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[25],"class_list":["post-40333","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>Warning: .NET content ahead! Yesterday, Brad Abrams noted that Char.IsLetter() matches more than just &#8220;A&#8221; through &#8220;Z&#8221;. What people might not realize is that Char.IsDigit() matches more than just &#8220;0&#8221; through &#8220;9&#8221;. Valid digits are members of the following category in UnicodeCategory: DecimalDigitNumber. But what exactly is a DecimalDigitNumber? DecimalDigitNumber Indicates that the character is [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/40333","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/users\/1069"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/comments?post=40333"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/40333\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media\/111744"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media?parent=40333"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=40333"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=40333"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}