Регулярные выражения (RegExp) для МКБ-10

Apr 28, 2020 16:41


МКБ-10 - это Международная Классификация Болезней, десятое прочтение. Каждая известная на данный момент человеческая болячка имеет свой код, состоящий из латинской буквы от A до Z и двух арабских цифр (00-99). Для кодирования более точного диагноза в конце добавляются точка и ещё одна арабская цифра.
Например, все болезни глаза кодируются буквой H. Если углубиться в классификацию на шаг дальше, можно найти болезни с кодом H52 - то есть, нарушения рефракции и аккомодации. А среди них есть достаточно известные H52.0 (гиперметропия, она же дальнозоркость) и H52.1 (миопия, она же близорукость).
Или ещё пример: самая нашумевшая на данный момент болезнь имеет коды U07.1 (COVID-19, вирус идентифицирован) и U07.2 (вирус не идентифицирован).
А теперь представим себе задачу. Перед нами - текст неограниченной длины (от пары абзацев до пары экземпляров «Войны и мира»). В этом тексте там и сям встречаются коды МКБ-10. Нужно найти ВСЕ коды, встречающиеся в тексте.


Первый способ - визуальный поиск. Увлекательные минуты, часы, сутки, недели...
Есть ещё способ. Как вы и сами знаете, в любом текстовом редакторе есть инструмент поиска, который вызывается сочетанием клавиш Ctrl + F. Да и не только в текстовом редакторе. Если вы читаете этот пост с компьютера или ноутбука, вы тоже можете запустить поисковик этим же сочетанием клавиш. В большинстве мобильных браузеров есть инструмент «Поиск на странице».
...И вот мы ищем. Диагноз за диагнозом. Код за кодом. Можно, конечно, ограничиться поиском заглавных латинских букв, но не факт, что эти латинские буквы будут именно началом кодов МКБ-10.
Наконец, третий способ. Думаю, самый быстрый. Состоит из двух шагов.
Шаг первый: находим закономерность, общую для всех текстов, которые мы хотим найти. И шаг второй: переводим эту закономерность на специальный формализованный язык. Так вот, регулярное выражение - это и есть наша закономерность, записанная на специальном формализованном языке. Сокращённо регулярные выражения называются регэкспами (от английского regular expressions, regex) или просто регулярками.
Не буду вдаваться в теорию регэкспов и перейду сразу к сути. Сперва напишу регулярное выражение, затем объясню, что оно значит.
Итак, регулярка для поиска кодов МКБ-10 в первом приближении выглядит следующим образом:

\b([A-Z]\d{2})(.\d)?\b

На первый взгляд может показаться, что я пустил на клавиатуру свою кошку. Но теперь давайте разберём нашу регулярку по косточкам:
  1. Выражение начинается и заканчивается символами \b. Это значит, что нам нужно целое слово, окружённое пробелами или знаками препинания; часть отдельного слова нам не нужна (ср. блок ада - блокада).
  2. Выражение состоит из двух частей, каждая из которых заключена в круглые скобки. К тому же после второй части стоит знак вопроса: ()()?. Это значит, что вторая часть выражения может быть, а может и не быть. А мы уже знаем, что код МКБ-10 состоит из двух частей: во-первых, буквы с двумя цифрами, во-вторых, одиночной цифры, которая от первой части отделяется точкой. И вторая часть может не использоваться. Так вот, часть регулярного выражения, которая может присутствовать или не присутствовать, отмечается знаком вопроса. А скобки нужны просто для того, чтобы отделить одну часть от другой.
  3. Теперь рассмотрим то, что находится в первой части. И начнём с [A-Z]. В квадратных скобках находится диапазон, то есть, несколько символов между начальным и конечным. A-Z значит, что нам нужны заглавные латинские буквы от A до Z, то есть, вообще все. Если мы хотим добавить строчные латинские буквы, то диапазон будет выглядеть так: [A-Za-z]. А диапазон для всех русских букв будет выглядеть так: [А-Яа-яЁё]. Таким образом, первым символом кода, который мы ищем, должна быть одна заглавная латинская буква из всего алфавита.
  4. За диапазоном следует \d. Этим сочетанием символов обозначаются все арабские цифры от 0 до 9. Как вы сами можете догадаться, диапазон для всех арабских цифр можно записать как [0-9]. Но два символа меньше, чем пять.
  5. Буква в коде одна, и для неё мы написали единственный диапазон. А вот цифры нужно две. Строго две, не больше и не меньше. Поэтому в фигурных скобках мы показываем количество цифр: {2}.
  6. Ну и вторая часть. Состоит она из точки (если нам нужен строго определённый символ, то здесь мы пишем его как есть, безо всяких дополнительных знаков) и одной цифры, то есть знакомого нам \d
В переводе на русский язык наш регэксп будет выглядеть примерно так:
  1. Нам нужно целое слово, а не часть слова.
  2. Нужное нам слово должно начинаться с любой заглавной латинской буквы.
  3. За буквой должны следовать строго две арабские цифры.
  4. После двух арабских цифр могут следовать (а могут и не следовать) точка (применение других знаков препинания недопустимо) и одна любая арабская цифра.
Это и есть закономерность, которой удовлетворяют все тексты, которые мы ищем. Согласитесь, искать с её помощью легко и просто, гораздо сложнее понять принцип составления регулярных выражений любой сложности.

Перейдём к практике. Проверить регулярные выражения в действии можно, например, вот на этом сайте. В поле REGULAR EXPRESSION вводим регулярное выражение, в поле TEST STRING - исследуемый текст. Сайт подсветит все фрагменты исходного текста, которые удовлетворяют регулярному выражению.



А если вы хотите использовать регулярки именно для поиска, то в данном случае самая простая программа - Notepad++, которую можно совершенно бесплатно скачать на официальном сайте. Вот пример поиска по регулярному выражению:



И всё было бы хорошо, но есть нюанс. Далеко не всегда за латинской буквой следуют две любые цифры. К примеру, если есть болезни с кодами A00-A99, то про болезни с литерой U этого не скажешь. Максимальное число есть у болезни с кодом U85. Поэтому, если мы хотим отлавливать только правильные коды МКБ, то регулярка для поиска одной только основной части будет выглядеть следующим образом:

([ABFGIL-OQ-SWXZ]\d{2}|C([0-8]\d|9[0-7])|D([0-7]\d|8[0-9])|E([0-8]\d|90)|H([0-8]\d|9[0-5])|K([0-8]\d|9[0-3])|P([0-8]\d|9[0-6])|T([0-8]\d|9[0-8])|U([0-7]\d|8[0-5])|V(0[1-9]|[1-9]\d)|Y([0-8]\d|9[0-8]))

Да, она длиннее исходной. Но её тоже можно разбить на отдельные понятные части. Правда, здесь есть один новый символ, вертикальная черта |. Этот символ используется в значении «ИЛИ».
Строго говоря, эта регулярка тоже не на сто процентов правильная. Она отлавливает только диапазоны чисел «от сих» и «до сих». Представьте себе, что болезни с кодом K28 было решено признать несуществующими исключить из классификатора. Но этот код попадает в заданный нами диапазон от 00 до 93, и поэтому всё равно будет найден. Следовательно, выражение нуждается в доработке. Если интересно, этой самой доработке я посвящу следующий пост.
Да, выражение длинное. Да, оно страшно выглядит. Но, если для поиска нам дали очень длинный текст, то составление регулярки значительно сократит время в дальнейшем.

P.S. Для примера был использован текст статьи М.В. Жуневой «Изображение болезни в художественных произведениях».
Коды МКБ добавлены в текст мной.

медицина, МКБ-10, regex, информатика, регулярные выражения, регулярки, регэкспы

Previous post Next post
Up