Границы и утверждения

Границы и утверждения

Технический фундамент позиционных проверок

Границы и утверждения не добавляют символы в совпадение, а проверяют позицию:

  • якоря ^ и $ фиксируют начало/конец строки;
  • \b проверяет границу слова;
  • lookaround проверяет контекст слева/справа без захвата;
  • строгие позиционные проверки критичны для валидаций формата.

Это инструмент точности: не просто "нашли что-то", а "нашли в нужном месте и окружении".

Зачем нужны границы и утверждения

Иногда важно не просто найти фрагмент текста, а проверить его позицию: в начале строки, в конце слова, перед определенным символом, но без включения этого символа в совпадение. Для этого в regex используют границы и утверждения (assertions).

Ключевой момент: утверждения проверяют условие в позиции, но не "съедают" символы.

Проверь себя: почему для проверки "строка начинается с ID" недостаточно просто /ID/?

Якоря начала и конца: ^ и $

  • ^ - начало строки;
  • $ - конец строки.
console.log(/^cat/.test('cat is here')); // true
console.log(/^cat/.test('my cat')); // false

console.log(/cat$/.test('my cat')); // true
console.log(/cat$/.test('cat here')); // false

Смотри, что важно: с якорями шаблон становится строгим, без них совпадение может быть "внутри" строки.

const codeRegex = /^\d{6}$/;
console.log(codeRegex.test('123456')); // true
console.log(codeRegex.test('id:123456')); // false

Смотри, что важно: в многострочном тексте якоря обычно относятся ко всей строке целиком. Флаг m (multiline) переключает ^ и $ на уровень отдельных строк.

const text = 'cat\nmy cat';
console.log(/^my/.test(text)); // false
console.log(/^my/m.test(text)); // true

Граница слова \b

\b проверяет границу между "символом слова" и "не словом".

console.log(/\bcat\b/.test('cat')); // true
console.log(/\bcat\b/.test('catalog')); // false

Это полезно, когда нужно найти слово целиком, а не часть другого слова.

Здесь часто путаются: \b работает по правилам \w, поэтому для некоторых языков/символов поведение может быть не тем, что ожидаешь.

Смотри, что важно: если ты создаешь regex через new RegExp('...'), то \b нужно экранировать как \\b, иначе в строке '\b' это будет "backspace", а не граница слова.

const r = new RegExp('\\\\bcat\\\\b');
console.log(r.test('my cat')); // true

Позитивный lookahead (?=...)

Проверяет, что после текущей позиции есть шаблон, но не включает его в результат.

const priceRegex = /\d+(?=\s?₽)/g;
console.log('Цена: 1200 ₽'.match(priceRegex)); // ['1200']

Мы получили число без символа валюты, но проверили, что валюта стоит рядом.

Негативный lookahead (?!...)

Проверяет, что после позиции нет указанного шаблона.

const regex = /foo(?!bar)/;
console.log(regex.test('foobar')); // false
console.log(regex.test('foobaz')); // true

Это удобно для исключения нежелательных контекстов.

Lookbehind (?<=...) и (?<!...)

Lookbehind проверяет контекст слева от позиции.

const amountRegex = /(?<=\$)\d+/g;
console.log('$120 and $45'.match(amountRegex)); // ['120', '45']

Дополнительный пример: извлечение домена только после @ через lookbehind.

const domainRegex = /(?<=@)[a-z0-9.-]+\.[a-z]{2,}/i;
console.log('user@mail.example.com'.match(domainRegex)?.[0]); // mail.example.com

Ключевой момент: само $ в результат не попадает, потому что это только условие позиции.

Проверь себя: почему это удобнее, чем сначала вырезать $, а потом отдельно парсить число?

Микро-сценарии из продукта

  1. Валидация одноразового кода (^\d{6}$) в форме подтверждения.
  2. Поиск целого слова в модерации контента (\bword\b).
  3. Извлечение сумм из текста счета через lookaround.

Все эти задачи требуют не только "что найти", но и "где это находится".

Частые ошибки новичков

  • Забывать якоря и получать ложные совпадения.
  • Путать \b с пробелами.
  • Пытаться использовать lookaround там, где достаточно простого группирования.
  • Делать чрезмерно сложный regex без поэтапной проверки.

Анти-провал: сначала напиши простой рабочий шаблон, затем добавляй границы и утверждения для ужесточения правил.

Что будет, если изменить входные данные

Для ^\d{6}$:

  • 123456 проходит;
  • 123456 не проходит (лишний пробел);
  • 1234567 не проходит (лишний символ);
  • abc123 не проходит (не цифры).

Это дает строгую и предсказуемую проверку.

Проверь себя: какой баг может появиться, если убрать $ из ^\d{6}$?

Краткий итог

  • Границы и утверждения задают позиционные условия для совпадений.
  • ^ и $ фиксируют начало и конец строки.
  • \b помогает искать целые слова, а не подстроки.
  • Lookahead/lookbehind проверяют контекст, не включая его в совпадение.
  • Эти инструменты особенно важны для строгой валидации и точного извлечения данных.