Skip to main content

Синтаксис регулярных выражений

  • Регулярные выражения. Цель: уметь уверенно читать/писать и переводить «самодельные маски» в стандартные регексы.
  1. Символьные классы и якоря
  • Класс: […]. Совпадение одного символа из перечисленных.

    • Диапазоны: [a-z], [A-Z], [0-9].
    • Отрицание: [^…] — любой символ, кроме указанных (работает только если ^ стоит сразу после [).
    • Экранирование внутри класса: спецсимволы — ], -, .
      • Чтобы записать ]: поместите первым или экранируйте: []A-Z] или ]
      • Для дефиса как литерала: [-A-Z] или [A-Z-]
      • Бэкслеш: [\]
  • Вне класса экранируйте: . ^ $ * + ? ( ) [ ] { } | \

  • Якоря: ^ — начало строки, $ — конец строки.

    • Используйте ^…$ или функцию “fullmatch”, чтобы проверять весь пароль, а не подстроку.
    • В многострочном режиме ^/$ — начало/конец строки, а не всего текста; для «жёстких» границ некоторые движки имеют \A и \z.
  1. Группы и альтернация
  • ( … ) — захватывающая группа; (?: … ) — незахватывающая.
  • Альтернация |: a|bc — «a» ИЛИ «bc». У | самый низкий приоритет — группируйте: (?:abc|def)ghi.
  • Ссылки на группы: \1, \2… (пригодится позже; здесь фиксируем, что скобки по умолчанию «захватывают»).
  1. Квантификаторы
  • ? — 0 или 1; + — 1 или более; * — 0 или более; {m,n} — от m до n.
  • Жадность/ленивость (*/+/? vs *?/+?/?):, детали — в модуле 3.
  1. Различия «внутри [ ]» и «снаружи [ ]»
  • Внутри класса мета-значение имеют только ^ (в начале), - (диапазон), ] (закрывает), \ (экранирует).
  • Символы |, *, +, ? внутри [ ] — обычные литералы.
    • Пример: [a|b*] соответствует одному из символов: a, |, b, . Это НЕ «a ИЛИ b».
  • Вне класса те же символы — операторы: | — альтернация, * — квантификатор и т.д.
  1. Практика: регексы под простые политики (ASCII-строго, без \d/\w)
  • P1. Только строчные латинские, длина 8–12

    • Регекс: ^[a-z]{8,12}$
    • Примеры: password12 ✗; passcode ✓; Passcode ✗
  • P2. Буквы/цифры, длина 6–10, минимум одна цифра

    • Регекс: ^(?=.*[0-9])[A-Za-z0-9]{6,10}$
    • Примеры: abcdef ✗; abcde9 ✓; ABCDEF ✗; A1b2C3d4 ✓
  • P3. Начинается с буквы, заканчивается цифрой; середина — буквы/цифры/подчёркивание; общая длина 6–12

    • Рассуждение: 1 буква + середина {4,10} + 1 цифра
    • Регекс: ^[A-Za-z][A-Za-z0-9_]{4,10}[0-9]$
    • Примеры: a____9 ✓; A12345 ✗ (конец не цифра); 9start1 ✗ (начало не буква)
  • P4. Буквы/цифры, длина ≥8, запрещены «похожие» символы O, 0, l, I

    • Регекс: ^(?!.*[O0lI])[A-Za-z0-9]{8,}$
    • Примеры: Pa55w0rd ✗ (0 запрещён); Passw0rd ✗; Passw9rd ✓; HELLOlll ✗
  • P5. Разрешены буквы/цифры/дефис/подчёркивание, длина 8–16, нельзя две подряд из [-_], начинаться должно с буквы/цифры

    • Идея: первый — буква/цифра; далее либо буква/цифра, либо одиночный - или _ не за которым снова - или _
    • Регекс: ^(?=.{8,16}$)[A-Za-z0-9](?:[A-Za-z0-9]|[-_](?![-_]))*$
    • Примеры: user–name ✗; user-name ✓; username ✗; username ✓; user__name ✗
  1. Мини-набор тестов (ожидаемое соответствие)
  • Для P1: [password ✓], [pass_word ✗], [abcdefgh ✓], [abc def ✗]
  • Для P2: [abcde9 ✓], [abcdef ✗], [A1b2C3d4 ✓], [ABCDEF1 ✓], [ABcdefghij1 ✗ (длина >10)]
  • Для P3: [a1234Z ✗], [a1234z9 ✓], [Start_1 ✓], [1start9 ✗], [A____9 ✓]
  • Для P4: [GoodPass9 ✓], [Pa55w0rd ✗], [IloveYou9 ✗], [safeSAFE2 ✓]
  • Для P5: [name_surname ✓], [name__surname ✗], [name-surname ✓], [name–surname ✗], [9name_ok ✓], [_name_ok ✗]
  1. Замечания по практике
  • Всегда добавляйте ^…$ (или используйте fullmatch) — иначе совпадёт подстрока.
  • Явно задавайте алфавит диапазонами: [A-Za-z0-9], избегайте \w и \d, если не уверены в Unicode-правилах двигателя.
  • В диапазонах помните порядок кодпоинтов: [A-z] захватывает лишние символы между Z и a. Используйте [A-Za-z].

Примеры по темам Модуля 2.

Символьные классы, диапазоны, отрицание, якоря

  • Один символ из набора:
    • Регекс: ^[abc]{3}$
    • Совпадения: cab ✓, aaa ✓; dad ✗
  • Диапазон:
    • Регекс: ^[a-z]{4}$
    • Совпадения: java ✓; Go ✗; abc5 ✗
  • Отрицание (не цифры):
    • Регекс: ^[^0-9]{3,5}$
    • Совпадения: abc ✓; a9b ✗
  • Якоря:
    • Строка “xxabcxx”: /abc/ ✓ (подстрока), /^abc$/ ✗ (вся строка должна быть ровно “abc”)

Экранирование (вне и внутри классов)

  • Вне класса . ^ $ * + ? ( ) [ ] { } | \ — спецсимволы.
    • Литерал точки:
      • Регекс: ^3.14$
      • Совпадения: 3.14 ✓; 3314 ✗
  • Внутри класса спецсимволы: ^ (в начале), - (диапазон), ] (закрытие), \ (экранирование).
    • Литерал дефиса:
      • Регекс: ^[A-Z-]{3}$
      • Совпадения: AB- ✓; A-C ✓; ABC ✓

Группы и альтернация

  • Захватывающая группа и |:
    • Регекс: ^(cat|dog)$
    • Совпадения: cat ✓; dog ✓; catt ✗; hotdog ✗
  • Незахватывающая группа (не создаёт \1):
    • Регекс: ^(?:red|green|blue)$
  • Важно группировать при |:
    • Неправильно: ^ab|cd$ (это «начинается с ab» ИЛИ «где-то есть cd»)
    • Правильно: ^(?:ab|cd)$

Квантификаторы

  • ? (0 или 1):
    • Регекс: ^colou?r$
    • Совпадения: color ✓; colour ✓; colouur ✗
    • (1 или более):
    • Регекс: ^[A-Za-z0-9]+$
    • Совпадения: abc123 ✓; "" ✗
    • (0 или более):
    • Регекс: ^ba*$ (b, ba, baa, …)
  • {m,n} (интервал):
    • Регекс: ^[0-9]{2,4}$
    • Совпадения: 12 ✓; 1234 ✓; 1 ✗; 12345 ✗

Разница внутри [ ] и снаружи

  • Внутри класса | и * — это обычные символы:
    • Регекс: ^[ab|*]{3}$ — один символ из {a, b, |, *}, ровно 3 раза
    • Совпадения: a|* ✓; ab| ✓
  • Снаружи это операторы:
    • Регекс: ^(?:a|b*)$ — либо “a”, либо буква b со звёздочкой как литералом
    • Совпадения: a ✓; b* ✓; b ✗

Мини‑практика: простые политики и тесты

  • Только строчные латинские, длина 8–12:
    • Регекс: ^[a-z]{8,12}$
    • Тесты: password ✓; pass_word ✗; ABCdefgh ✗
  • Буквы/цифры, длина 6–10, минимум одна цифра:
    • Регекс: ^(?=.*[0-9])[A-Za-z0-9]{6,10}$
    • Тесты: abcdef ✗; abcde9 ✓; ABCDEF1 ✓; ABcdefghij1 ✗ (длинно)
  • Начинается с буквы, заканчивается цифрой; середина — буквы/цифры/подчёркивание; общая длина 6–12:
    • Регекс: ^[A-Za-z][A-Za-z0-9_]{4,10}[0-9]$
    • Тесты: a____9 ✓; 9start1 ✗; A12345 ✗ (конец не цифра)
  • Буквы/цифры, длина ≥8, запрет символов O, 0, l, I:
    • Регекс: ^(?!.*[O0lI])[A-Za-z0-9]{8,}$
    • Тесты: Pa55w0rd ✗; GoodPass9 ✓; IllIlIll ✗

Мини‑шпаргалка

  • Классы: [abc] — один из; диапазоны: [a-z]; отрицание: [^...] (только если ^ сразу после [)
  • Экранирование вне класса: . ^ $ * + ? ( ) [ ] { } | \
  • Внутри класса экранируем ] - \ при необходимости.
  • Якоря: ^ начало, $ конец. Для полной проверки строки всегда используйте ^...$ или fullmatch.
  • Группы: ( … ) — захватывающая; (?: … ) — незахватывающая.
  • Альтернация: x|y (группируйте: (?:abc|def)).
  • Квантификаторы: ? (0/1), + (1+), * (0+), {m,n}.
  • Просмотры (lookahead) для «должно содержать/запрещено»: (?= … ), (?! … ).
  • Разница внутри/снаружи [...]: внутри | * + ? — обычные символы; мета — только ^ - ] \.

Типовые ошибки

  • [A-z] вместо [A-Za-z] — захватывает лишние символы между Z и a.
  • Нет якорей ^$ — совпадение с подстрокой.
  • Неправильная альтернация: ^ab|cd$ вместо ^(?:ab|cd)$.
  • Бездумные \w, \d: в Unicode‑режимах они шире ASCII и могут давать «лишние» совпадения.

Практика: базовые политики (ASCII‑строго)

  • P1. Только строчные латинские, длина 8–12
    Регекс: ^[a-z]{8,12}$
  • P2. Буквы/цифры, длина 6–10, минимум одна цифра
    Регекс: ^(?=.*[0-9])[A-Za-z0-9]{6,10}$
  • P3. Начинается с буквы, заканчивается цифрой; середина — [A-Za-z0-9_]; общая длина 6–12
    Регекс: ^[A-Za-z][A-Za-z0-9_]{4,10}[0-9]$
  • P4. Буквы/цифры, длина ≥8, запреты: O, 0, l, I
    Регекс: ^(?!.*[O0lI])[A-Za-z0-9]{8,}$
  • P5. Разрешены [A-Za-z0-9-_], длина 8–16, нельзя две подряд из -/_, начинается буквой/цифрой
    Регекс: ^(?=.{8,16}$)[A-Za-z0-9](?:[A-Za-z0-9]|[-_](?![-_]))*$

Как читать шаблон (P2, по шагам)

^(?=.*[0-9])[A-Za-z0-9]{6,10}$

  1. ^$ — вся строка, не подстрока.
  2. (?=.*[0-9]) — есть хотя бы одна цифра.
  3. [A-Za-z0-9]{6,10} — длина 6–10 из заданного алфавита.

Мини‑тренинг (5–10 минут)

  1. Прочитайте: ^(?=.*[A-Z])(?=.*[0-9])[A-Za-z0-9]{8,12}$
    Ответьте: алфавит? длина? обязательные классы?
  2. Постройте шаблон: «начинается с заглавной, далее 5–9 строчных/цифр, заканчивается не цифрой».
    Эталон: ^[A-Z][a-z0-9]{5,9}[^0-9]$
  3. Исправьте: ^[A-z]{6,}$ → только латинские буквы.
    Эталон: ^[A-Za-z]{6,}$
  4. Запретите подряд идущие спецсимволы из [-_.], разрешая их по одному; длина 6–12; алфавит [A-Za-z0-9-_.].
    Эталон: ^(?=.{6,12}$)[A-Za-z0-9](?:[A-Za-z0-9]|[-_.](?![-_.]))*$
  5. Составьте регекс: «строчные латинские и цифры, ровно 10, хотя бы три буквы и две цифры».
    Подсказка: можно через просмотры: ^(?=(?:.*[a-z]){3,})(?=(?:.*[0-9]){2,})[a-z0-9]{10}$

Как тестировать корректно

  • Используйте regex101 (PCRE) или встроенные средства IDE.
  • Для строгого ASCII — задавайте диапазоны вручную, избегайте \w и \d.
  • Всегда добавляйте якоря ^…$ или используйте fullmatch.
  • Готовьте короткие, целевые тест‑строки: положительные/отрицательные/крайние случаи.

Приложение A. Тестовые строки (см. также файл corpus.txt)

Ниже — компактные наборы для P1–P5.

  • P1 (^[a-z]{8,12}$)
    • Плюс: password, abcdefgh, hellothere
    • Минус: pass_word, ABCdefgh, abc def
  • P2 (^(?=.*[0-9])[A-Za-z0-9]{6,10}$)
    • Плюс: abcde9, A1b2C3d4, ABCDEF1
    • Минус: abcdef, ABcdefghij1 (длинно), abc$123 (лишний символ)
  • P3 (^[A-Za-z][A-Za-z0-9_]{4,10}[0-9]$)
    • Плюс: a____9, Start_1, A1b2c3d4e5f6g7h8i9 ✗ (длинно)
    • Минус: 9start1, A12345 (конец не цифра)
  • P4 (^(?!.*[O0lI])[A-Za-z0-9]{8,}$)
    • Плюс: GoodPass9, safeSAFE2
    • Минус: Pa55w0rd, IllIlIll, HELLOlll
  • P5 (^(?=.{8,16}$)[A-Za-z0-9](?:[A-Za-z0-9]|[-_](?![-_]))*$)
    • Плюс: name_surname, name-surname, username_
    • Минус: name__surname, name--surname, _username (начинается не буквой/цифрой)

Нужен ли «lorem ipsum»?

Не нужен. Для обучения регексам полезнее короткие и точные тест‑строки, покрывающие границы: минимальные/максимальные длины, наличие/отсутствие обязательных классов, запрещённые символы, позиционные условия. Если всё же нужен «корпус» для экспериментов с подстроками, используйте примеры строк и проверяйте разницу между /abc/ и /^abc$/.

Примеры строк:
- The quick brown fox jumps over 13 lazy dogs.
- Start_1 middle_text end9
- password PASSword Pa55w0rd GoodPass9
- a____9 A12345 9start1
- name_surname name--surname username_ _username
- abcde9 abcdef ABCDEF1 ABcdefghij1
- HELLOlll IllIlIll safeSAFE2
- abc def abc_def abc-def
- 123456 0000000000 1234567890

Шпаргалка‑чек‑лист перед сдачей решения

  • Есть ^ и $?
  • Алфавит задан явно? (ASCII/Unicode?)
  • Длина корректна?
  • «Хотя бы/запретить» через (?=...) / (?!...)?
  • Альтернации сгруппированы (?:...|...)?
  • Нет ли [A-z], неожиданного \w/\d?