TGViewer
.NET Разработчик .NET Разработчик @netdeveloperdiary · 6.76K subscribers
Post #1633 1.48K
День 1316. #ЗаметкиНаПолях
Неочевидные Различия в Regex
1. \d или [0-9]
В документации .NET про Regex, \d означает любую цифру. Что означает термин «цифра», зависит от опций выражения:
- по умолчанию, без опции RegexOptions.ECMAScript, \d означает \p{Nd}, т.е. любой символ из категории «цифр» в Unicode;
- с опцией RegexOptions.ECMAScript \d означает [0-9].

Категория цифр в Unicode содержит цифры 0, 1, 2, … но также цифры из других языков, вроде ٣, ٧, ൩ или ໓. Полный список состоит из 610 символов!
Поэтому
Regex.IsMatch("०१२३४५६७८९", "[0-9]{10}"); 
вернёт False, тогда как
Regex.IsMatch("०१२३४५६७८९", "\\d{10}");
вернёт True.

Добавление опции решает проблему:
Regex.IsMatch("०१२३४५६७८९", "\\d{10}", RegexOptions.ECMAScript);
вернёт False.

2. [a-zA-Z] или [a-z] с IgnoreCase
Рассмотрим два регулярных выражения:
var regex1 = new Regex("^[a-zA-Z]+$");
var regex2 = new Regex("^[a-z]+$",
RegexOptions.IgnoreCase |
RegexOptions.CultureInvariant);

В большинстве случаев они работают одинаково, так, как мы и предполагаем:
regex1.IsMatch("Test"); // True
regex2.IsMatch("Test"); // True

Однако, есть специальный символ K (U+212A), обозначающий температуру по Кельвину, и здесь всё интереснее:
regex1.IsMatch("K"); // False
regex2.IsMatch("K"); // True

Когда в регулярном выражении указан параметр RegexOptions.IgnoreCase, сравнение между входными данными и шаблоном будет выполняться без учёта регистра. Чтобы поддерживать это, Regex необходимо определить, какие отображения регистра будут использоваться для сравнений. Отображение регистра существует всякий раз, когда у вас есть два символа «A» и «B», где либо:
- «A» является ToLower() представлением «B»,
- оба символа являются представлением в нижнем регистре для одного и того же символа.

В этом случае char.ToLowerInvariant('K') - это k (строчная латинская буква K). Поэтому второе выражение возвращает True для знака Кельвина, однако он не входит в множество [a-zA-Z], поэтому первое выражение возвращает False.

Источник: https://www.meziantou.net/regex-with-ignorecase-option-may-match-more-characters-than-expected.htm
  • 👍 21
More from @netdeveloperdiary
  1. Oct 13, 2026День 2813. #ЗаметкиНаПолях #Async Ещё Раз Про Async/Await в C#. Часть 1 1. Почему существу…
  2. Oct 12, 2026День 2812. #Карьера #AI Как Разработчикам Оставаться Полезными, Когда Код Пишет ИИ? По мер…
  3. Oct 11, 2026День 2811. #ВопросыНаСобеседовании Марк Прайс предложил свой набор из 60 вопросов (как тех…
  4. Oct 10, 2026День 2810. #ЧтоНовенького #VSCode Более Быстрый и Лёгкий C# Dev Kit Мы, разработчики, люби…
  5. Oct 9, 2026День 2809. #Карьера 5 Навыков, Которые Помогут Быстрее Стать Сеньором. Окончание Начало 3.…
  6. Oct 8, 2026День 2808. #Карьера 5 Навыков, Которые Помогут Быстрее Стать Сеньором. Начало В ИТ есть се…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →