[[help:strings|Назад: Строки]] ====== Регулярные выражения ====== Этот раздел может на первый взгляд показаться сложным. На самом деле в регулярных выражениях ничего особо сложного нет. То, что вам кажется непонятной абракадаброй, при должной сноровке легко читается. Тем не менее данный раздел можно спокойно пропустить, и вернуться к его изучению позже. **Регулярные выражения** — это просто шаблоны, которые используются различными функциями для поиска в тексте фрагментов, точное значение которых неизвестно. Например, регулярное выражение позволяет отыскать в тексте слово из шести букв, оканчивающееся на "ка". Это может быть и слово "аптека", и слово "оптика", и слово "спичка", и слово "опушка". Регулярные выражения ещё называют **регулярками**, **масками** и **регэкспами**. Сами по себе регулярные выражения ничего делать не умеют. Как мы уже выяснили, это просто шаблоны для строк. Но эти шаблоны вы можете использовать в специальных функциях. ===== Функции, использующие регулярные выражения ===== * ''%%STRCOMP([$строка],[$шаблон])%%'' - проводит сравнение строки ''%%[$строка]%%'' на соответствие регулярному выражению ''%%[$шаблон]%%''. Возвращает ''%%1%%'', если строка соответствует шаблону, иначе ''%%0%%''. Сравни с функцией ''%%$STRFIND%%''. strcomp('иду по дороге','\s?\S+\s+\S+\s+\S+\s?') & ! вернёт 1 strcomp(' иду домой','\s?\S+\s+\S+\s+\S+\s?') & ! вернёт 0 strcomp(' иду в лес ','\s?\S+\s+\S+\s+\S+\s?') & ! вернёт 1 strcomp('однословие','\s?\S+\s+\S+\s+\S+\s?') & ! вернёт 0 * ''%%$STRFIND([$строка],[$шаблон],[#номер])%%'' - эта функция ищет в строке ''%%[$строка]%%'' подстроку, соответствующую регулярному выражению ''%%[$шаблон]%%'', и возвращает эту подстроку. ! функция найдёт слово из четырёх букв $STRFIND('идти к пещере', '\b\w{4}\b') &! на экране увидим 'идти' * Если указан ''%%[#номер]%%'', то функция возвращает не всю найденную подстроку, а только ту её часть которая соответствует группе с указанным номером ''%%[#номер]%%''. Группы нумеруются слева направо, сначала внешние, а потом внутренние, начиная с **1**. ! первая группа в первых скобках, вторая во вторых, третья - в скобках, вложенных во вторые $STRFIND('+33-671-190-23-999', '\+\d{1,2}-(\d{3})((-\d+)+)',1) &! на экране увидим '671' $STRFIND('+33-671-190-23-999', '\+\d{1,2}-(\d{3})((-\d+)+)',2) &! на экране увидим '-190-23-999' $STRFIND('+33-671-190-23-999', '\+\d{1,2}-(\d{3})((-\d+)+)',3) &! на экране увидим '-999' * Если подстрока с указанным номером отсутствует, то возвращается пустая строка. ! пытаемся отыскать числа в строке без чисел $STRFIND('Восемь зелёных яблок в корзине','\d+') &! на экране будет пустая строка * Ещё примеры: $STRFIND('идти к пещере', '^(\S+)\s(\S+)\s(\S+)$', 0) &! 'идти к пещере' $STRFIND(' идти к пещере', '^(\S+)\s(\S+)\s(\S+)$', 0) &! '' $STRFIND('идти к пещере', '^(\S+)\s(\S+)\s(\S+)$', 1) &! 'идти' $STRFIND('идти к пещере', '^(\S+)\s(\S+)\s(\S+)$', 2) &! 'к' $STRFIND('идти к пещере', '^(\S+)\s(\S+)\s(\S+)$', 3) &! 'пещере' $STRFIND('идти к дому', 'к\s(\S+)', 0) &! 'к дому' $STRFIND('идти к дому', 'к\s(\S+)') &! 'к дому' $STRFIND('идти к дому', 'к\s(\S+)', 1) &! 'дому' $STRFIND('идти к своему дому', 'к\s(\S+)', 1) &! 'своему' * ''%%STRPOS([$строка],[$шаблон],[#номер])%%'' - эта функция похожа на функцию ''%%$STRFIND%%'', то есть она ищет в строке ''%%[$строка]%%'' подстроку, соответствующую регулярному выражению ''%%[$шаблон]%%''. Однако, в отличие от функции ''%%$STRFIND%%'', она возвращает номер символа, с которого начинается вхождение найденной подстроки в указанную строку ''%%[$строка]%%''. ! функция найдёт слово из трёх букв, и вернёт номер первого символа, ! с которого это слово начинается STRPOS('Здесь три слова.', '\b\w{3}\b') &! на экране увидим 7 * Если указан ''%%[#номер]%%'', то функция возвращает номер символа, с которого начинается вхождение не всей подстроки, а только той её части, которая соответствует группе с указанным номером ''%%[#номер]%%''. Группы нумеруются слева направо, сначала внешние, а потом внутренние, начиная с **1**. !------'----5--8------15--' STRPOS('+33-671-190-23-999', '\+\d{1,2}-(\d{3})((-\d+)+)',1) &! на экране увидим 5 STRPOS('+33-671-190-23-999', '\+\d{1,2}-(\d{3})((-\d+)+)',2) &! на экране увидим 8 STRPOS('+33-671-190-23-999', '\+\d{1,2}-(\d{3})((-\d+)+)',3) &! на экране увидим 15 * Если подстрока с указанным номером отсутствует, то возвращается **0**. ! пытаемся отыскать числа в строке без чисел STRPOS('Восемь зелёных яблок в корзине','\d+') &! на экране будет 0 * Ещё примеры: STRPOS('идти к пещере', '^(\S+)\s(\S+)\s(\S+)$', 0) &! 1 STRPOS(' идти к пещере', '^(\S+)\s(\S+)\s(\S+)$', 0) &! 0 STRPOS('идти к пещере', '^(\S+)\s(\S+)\s(\S+)$', 1) &! 1 STRPOS('идти к пещере', '^(\S+)\s(\S+)\s(\S+)$', 2) &! 6 STRPOS('идти к пещере', '^(\S+)\s(\S+)\s(\S+)$', 3) &! 8 STRPOS('идти к пещере', '^(\S+)\s(\S+)(\s(\S+))?$', 4) &! 8 STRPOS('идти к дому', 'к\s(\S+)', 0) &! 6 STRPOS('идти к дому', 'к\s(\S+)') &! 6 STRPOS('идти к дому', 'к\s(\S+)', 1) &! 8 STRPOS('идти к своему дому', 'к\s(\S+)', 1) &! 8 * ''%%ARRCOMP([$имя_массива],[$шаблон],[#начало])%%'' - возвращает номер элемента массива ''%%[$имя_массива]%%'', соответствующего регулярному выражению ''%%[$шаблон]%%''. Поиск начинается с элемента с номером ''%%[#начало]%%''; индексация элементов массива ведётся с нуля. Если указанное значение не найдено, функция возвращает **-1**. * Подробное описание функции с примерами в разделе "[[help:arrays|Массивы]]". ===== Операторы, использующие регулярные выражения ===== * ''%%SCANSTR [$имя_массива], [$текст_для_разбора], [$регэксп], [#номер_группы]%%'' — оператор ищет в строке ''%%[$текст_для_разбора]%%'' непересекающиеся фрагменты, соответствующие регулярному выражению ''%%[$регэксп]%%'', и помещает их в массив ''%%[$имя_массива]%%''. Если параметр ''%%[#номер_группы]%%'' указан и отличается от нуля, в массив помещается не весь фрагмент целиком, а лишь та его часть, которая соответствует группе с указанным номером. * Подробное описание оператора и примеры использования в разделе "[[help:arrays|массивы]]". ===== Как научиться писать регулярные выражения ===== Почитайте наш самоучитель по составлению регулярных выражений: * [[regex:start|Самоучитель по регулярным выражениям]] На канале, посвящённом написанию игр на QSP, есть отдельное видео по регуляркам: * [[https://youtu.be/2ERAQw1M-yA|Уроки по QSP. Номер 23. Регулярные выражения]] Ещё есть прекрасное видео на канале Алекса Лущенко: * [[https://youtu.be/_pLpx6btq6U|Не бойтесь регулярных выражений. Regex за 20 минут!]] Полезные сайты: * [[http://regexcrossword.com|Игровое обучение регуляркам - regexcrossword.com]] * [[http://regex101.com/|Тестирование регулярок онлайн - regex101.com]] * [[https://regexper.com|Вводим свою регулярку и получаем объяснение - regexper.com]] * [[https://regexone.com|Обучающий материал на английском - regexone.com]] ===== Основные элементы синтаксиса регулярок в QSP ===== Основные поддерживаемые в **QSP** операции при записи регулярных выражений (для более подробной информации смотрите помощь по регулярным выражениям (PCRE)): ==== Метасимволы ==== * ''%%\%%'' — Экранирующий символ. * ''%%|%%'' — Выбор из альтернатив "или|или" * ''%%()%%'' — Группировка, т.е. задание групп * ''%%[]%%'' — объединение символов в класс, например чётные цифры "[02468]". Такое объединение считается за один символ. ==== Фиксаторы ==== * ''%%^%%'' — Начало строки * ''%%$%%'' — Конец строки * ''%%\b%%'' — Граница слова * ''%%\B%%'' — Не граница слова ==== Квантификаторы ==== * ''%%*%%'' — 0 или более вхождений символа или группы. * ''%%+%%'' — 1 или более вхождений символа или группы. * ''%%?%%'' — 0 или 1 вхождение символа или группы. * ''%%{n}%%'' — Ровно n вхождений символа или группы. * ''%%{n,}%%'' — От n вхождений, и более, символа или группы * ''%%{,m}%%'' — От 0 до m вхождений символа или группы * ''%%{n,m}%%'' — От n до m вхождений символа или группы * ''%%*?%%'' — "Ленивое" ''%%*%%'' * ''%%+?%%'' — "Ленивое" ''%%+%%'' * ''%%??%%'' — "Ленивое" ''%%?%%'' * ''%%{n}?%%'' — "Ленивое" ''%%{n}%%'' * ''%%{n,}?%%'' — "Ленивое" ''%%{n,}%%'' * ''%%{,m}?%%'' — "Ленивое" ''%%{,m}%%'' * ''%%{n,m}?%%'' — "Ленивое" ''%%{n,m}%%'' ==== Спецсимволы ==== * ''%%\t%%'' — Табуляция * ''%%\n%%'' — Перевод строки * ''%%\r%%'' — Возврат каретки ==== Спецсимволы предопределенных классов символов ==== * ''%%.%%'' — Любой символ * ''%%\w%%'' — Буква, цифра или символ подчёркивания * ''%%\W%%'' — Не входит в ''%%\w%%'', т.е. не буква, не цифра и не символ подчёркивания * ''%%\s%%'' — Пробельный символ * ''%%\S%%'' — Не пробельный символ * ''%%\d%%'' — Цифра * ''%%\D%%'' — Не цифра * ''%%\h%%'' — Шестнадцатиричная цифра (''%%[ABCDEFabcdef0123456789]%%'') * ''%%\H%%'' — Не входит в **\h**, т.е. не шестнадцатеричная цифра ==== Свойства символов ==== * ''%%\p{имя свойства}%%'' Свойство * ''%%\p{^имя свойства}%%'' Отрицание * ''%%\P{имя свойства}%%'' Отрицание Возможные названия свойств: **Alnum, Alpha, Blank, Cntrl, Digit, Graph, Lower, Print, Punct, Space, Upper, XDigit, Word, ASCII** Также поддерживаются обратные ссылки: ''%%\G%%'', где ''%%G%%'' - номер группы [[help:tuples|Вперёд: Кортежи]]