В этом посте я попытаюсь объяснить на простых примерах, что такое поисковые запросы JS RegExp.

Представим, что вам нужно ввести текст в стиле пин-кода. Что-то вроде этого:

Заметили, что все цифры точки кроме последней? Это действительно легко реализовать с помощью всего одной строчки кода, используя поисковый запрос RegExp (в данном случае отрицательный прогноз):

pin.replace(/\d(?!$)/g, ‘•’)

Что же здесь произошло? Мы разберемся, но сначала рассмотрим более простой пример.

У нас есть строка Markdown:

- 1 potato for 2€
- 2 tomatoes for 3€
- 5 bananas for 4€

Давайте напишем код, который находит все цифры перед знаком евро. С помощью обходных путей это можно сделать так:

str.match(/\d+(?=€)/g)

Вот что это значит:

  • \ d + Одна или несколько цифр
  • (? = €), за которым следует €

Вот и все! Вообще-то ежу понятно.

Это (? = your_regexp) называется положительным прогнозом. Вы можете интерпретировать это так, потому что он смотрит в будущее с позитивным отношением к тому, что будет дальше.

В результате вы получите массив:

[“2”, “3”, “4”]

Обратите внимание, что он вернул то, что было до просмотра вперед, в нашем случае это \ d +. Сам знак € не включается в результирующий массив.

Теперь я хочу найти все цифры, за которыми не стоит знак €. Это тоже очень просто.

str.match(/\d+(?!€)/g)

Это негативный прогноз. Основное отличие - знак ! вместо =.

Итак, этот вернет количества:

[“1”, “2”, “5”]

Это именно те цифры, которые мне нужны.

Теперь мы можем вернуться к нашему примеру с пин-кодом:

pin.replace(/\d(?!$)/g, ‘•’)
  • \ d Просто цифра
  • (?! $) Без конца строки ($ в регулярных выражениях - это специальный символ, обозначающий конец строки)

Подводя итог, найдите все цифры, которые не находятся в конце строки, и замените их знаком «•». Легкий!

Что ж, если есть предварительный просмотр, вероятно, должен быть ретроспективный просмотр. И да, он есть.

В отличие от €, $ обычно пишется перед цифрой.

- 1 potato for $2
- 2 tomatoes for $3
- 5 bananas for $4

Чтобы найти значения сейчас, нам понадобится немного другой код:

str.match(/(?<=\$)\d+/g)

Это называется позитивным взглядом назад. Затем экранированный знак $ (поскольку мы не хотим рассматривать его как конец строки, мы экранируем его обратной косой чертой).

Он находит все цифры, которым предшествует знак $.

С другой стороны, существует (? ‹! your_regexp) отрицательный просмотр назад.

str.match(/(?<!\$)\d+/g

Что находит все цифры, которым не предшествует знак $.

В заключение, если вам нужно найти что-то, за чем следует или не следует, используйте следующие:

  • Положительный прогноз: (? = your_regexp)
  • Отрицательный прогноз: (?! your_regexp)

Если вам нужно найти что-то, чему предшествовало или не предшествовало, используйте эти:

  • Позитивный просмотр назад: (? ‹= your_regexp)
  • Отрицательный просмотр назад: (? ‹! your_regexp)

Чтобы самостоятельно проверить все примеры, воспользуйтесь regex101. Это отличное место для проверки всех ваших регулярных выражений.

P.S. Будьте осторожны с использованием lookbehind в JS, так как он частично поддерживается на момент написания этого поста. Для уверенности отметьте caniuse.