воскресенье, 1 марта 2009 г.

Под Char.IsDigit() подходит больше символов, чем только "0".."9"

Это перевод Char.IsDigit() matches more than just "0" through "9". Автор: Реймонд Чен.

Внимание: впереди тема .NET!
Вчера, Брэд Абрамс заметил, что метод Char.IsLetter() фильтрует больший диапазон символов, чем просто от "A" до "Z".
Но что люди действительно могут не осознавать, так это то, что Char.IsDigit() соответствует не только символам от "0" до "9".
Допустимые цифры являются членами следующей категории в UnicodeCategory: DecimalDigitNumber.
Но что конкретно принадлежит DecimalDigitNumber?
DecimalDigitNumber
Указывает, что символ является десятичной цифрой; т.е. находится в диапазоне от 0 до 9. Обозначается Unicode названием "Nd" (номер, десятичная цифра). Имеет код 8.
К этому моменту вам нужно зайти на сайт Unicode Standard Committee, чтобы посмотреть, что же в точности принимается за "Nd", и тогда вы затеряетесь в запутанном лабиринте различных спецификаций и документов.

Давайте проведём эксперимент.
class Program {
public static void Main(string[] args) {
System.Console.WriteLine(
System.Text.RegularExpressions.Regex.Match(
"\x0661\x0662\x0663", // "١٢٣"
"^\\d+$").Success);
System.Console.WriteLine(
System.Char.IsDigit('\x0661'));
}
}
Символы в строке являются арабскими цифрами - но они всё же цифры, что и подтверждается следующим выводом программы:
True
True
Ой. А нет ли у вас бага при проверке параметров? Если вы использовали шаблон типа @"^\d$" для проверки того, что вы получили только цифры, а потом позже использовали System.Int32.Parse() для парсинга этой строки, тогда я могу скормить вам несколько арабских цифр, откинуться на спинку кресла и наслаждаться получившимся фейерверком. Арабские цифры пройдут ваши проверки, но как только вы попытаетесь использовать - бум! - вы возбуждаете System.FormatException и умираете.

Читать далее.

2 комментария:

Можно использовать некоторые HTML-теги, например:

<b>Жирный</b>
<i>Курсив</i>
<a href="http://www.example.com/">Ссылка</a>

Вам необязательно регистрироваться для комментирования - для этого просто выберите из списка "Анонимный" (для анонимного комментария) или "Имя/URL" (для указания вашего имени и ссылки на сайт). Все прочие варианты потребуют от вас входа в вашу учётку (поддерживается OpenID).

Пожалуйста, по возможности используйте "Имя/URL" вместо "Анонимный". URL можно просто не указывать.

Ваше сообщение может быть помечено как спам спам-фильтром - не волнуйтесь, оно появится после проверки администратором.