Регулярные выражения — мощный инструмент для работы со строковыми данными. В Stata 18 регулярные выражения стали еще мощнее и получили больше возможностей.
Обзор
Регулярные выражения используются для
-
проверка данных, например, проверка правильности формирования телефонного номера;
-
извлечение данных, например, для извлечения телефонных номеров из строки; и
-
преобразование данных, например, для нормализации различных вводимых телефонных номеров.
Stata предоставляет два набора функций регулярных выражений: regexm(), regexr() и regexs(), основанные на байт-потоке; и ustrregexm(), ustrregexrf(), ustrregexra() и ustrregexs(), основанные на Юникоде. Функции регулярных выражений на основе Юникода построены поверх библиотек ICU.
В Stata 18 функции, основанные на байт-потоке, обновлены и используют библиотеку Boost в качестве движка. Функции контролируются по версии пользователя, чтобы сохранить старое поведение, если пользователь указывает версию 17:.
Хорошее обсуждение регулярных выражений в Stata можно найти в руководстве Asjad Naqvi по Stata.
Старая реализация основана на алгоритме NFA Генри Спенсера и практически идентична стандарту POSIX.2. Новая реализация в Stata 18 имеет больше возможностей. Например, новая реализация поддерживает {n} для соответствия регулярному выражению ровно n раз:
. display regexm("123", "\d{3}") 1 . version 17: display regexm("123", "\d{3}") 0
Добавлен набор новых функций, использующих исключительно библиотеку Boost:
-
regexmatch() выполняет сопоставление регулярного выражения со строкой ASCII.
-
regexreplace() заменяет первую подстроку, соответствующую регулярному выражению, на указанный текст.
-
regexreplaceall() заменяет все подстроки, соответствующие регулярному выражению, на указанный текст.
-
regexcapture() возвращает подвыражение из предыдущего совпадения.
-
regexcapturenamed() возвращает подвыражение, соответствующее совпадающей именованной группе в регулярном выражении из предыдущего совпадения.
Давайте посмотрим, как это работает
Мы хотим найти и извлечь номера телефонов в адресах глав правительств.
Нам требуются следующие правила:
-
Номер телефона следует за «Phone:» или «tel:».
-
Он может начинаться с «+».
-
После «+» или в начале он содержит от 1 до 3 ненулевых цифр.
-
После этого в нем может быть от 7 до 32 цифр, пробел или «-«.
Мы хотим сгенерировать переменную phone для извлеченного номера телефона, который не содержит «Phone:» или «tel:», если адрес совпадает.
Мы хотим сгенерировать еще одну переменную, address1, чтобы заменить номер телефона на извлеченный номер телефона, указанный выше, за которым следует «tel:».

Компоненты регулярного выражения в локальном макросе reg выглядят следующим образом:
-
(?:Phone\:[\s]*?|tel\:[\s]*)— поиск «Phone:» или «tel:» без пробелов или с пробелами, но без захвата совпадения.
-
([+]{0, 1}[1-9]{1, 3}[0-9\s-]{7,32})— поиск и захват регулярного выражения, удовлетворяющего следующим условиям:
-
[+]{0, 1} — может начинаться с «+».
-
[1-9]{1, 3}— после «+» или в начале, он содержит от 1 до 3 ненулевых цифр.
-
[0-9\s-]{7,32} — после него может быть от 7 до 32 цифр, пробел или «-«.
-
Мы видим, что третий адрес не содержит ни «Phone:», ни «tel:» и, следовательно, не соответствует регулярному выражению, поэтому телефон в этом наблюдении отсутствует.