[[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|Вперёд: Кортежи]]