В этом посте я попытаюсь объяснить на простых примерах, что такое поисковые запросы 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.