Регулярные выражения в jQuery: как сделать их не жадными
Пройдите тест, узнайте какой профессии подходите
Быстрый ответ
Для превращения жадного регулярного выражения в нежадное следует добавить символ ?
после таких квантификаторов, как *
и +
. Это скажет движку регулярных выражений искать наименьшее возможное совпадение.
Например:
- Жадное:
/.* /
- Нежадное:
/.*?/
Пример кода:
let str = "Ранняя пташка ловит червяка.";
let match = str.match(/.*? ловит/); // "Пташка" появится сразу после этого фрагмента
console.log(match[0]); // "Ранняя пташка ловит"
Переход от жадного к нежадному
Важно разбираться в различиях между жадными и нежадными (или ленивыми) совпадениями при работе с регулярными выражениями. Жадное выражение стремится захватить максимальный объем контенту, тогда как нежадное выбирает минимальные варианты.
Нежадные регулярные выражения: ассеты обработки данных
Нежадные выражения неоценимы при анализе текстов с блоками специальных символов или частыми разделителями. Они останавливают поиск сразу после встречи первого соответствия, что помогает избежать захвата лишнего и позволяет извлечь множество результатов из одной строки данных.
В каких случаях применять нежадные выражения
- Анализировать HTML/XML теги с их многоуровневой вложенностью
- Выделять текст между кавычками или скобками
- Обрабатывать данные с одинаковыми начальными и конечными символами
Усовершенствование выражений: классы исключения и владеющие квантификаторы
Вы можете использовать классы исключения (например, [^)]*
для исключения всего, что идет за закрывающей скобкой) и владеющие квантификаторы (*+
для предотвращения отката) для повышения эффективности регулярных выражений.
Глобальный поиск: флаг "g" в регулярных выражениях
Используйте флаг g
для захвата всех совпадений в строке, а не просто первого:
let str = "Найдите (первую) и (вторую) пару скобок.";
let matches = [...str.matchAll(/\(.*?\)/g)]; // Немо в этот раз не имеет отношения к поиску скобок!
console.log(matches.map(m => m[0])); // ["(первую)", "(вторую)"]
Визуализация
Представим, что нежадное регулярное выражение – это белка (🐿️), которая собирает орехи:
Жадная белка: 🐿️🥜🥜🥜🥜🥜🥜🥜🥜🥜.... она заберет все орехи разом!
Нежадная белка: 🐿️🥜?... она соберет столько, сколько ей требуется и уйдет!
Это аналогично регулярным выражениям:
// Жадное регулярное выражение:
// Это белка, стремящаяся собрать все и сразу: "Чем больше, тем лучше!"
/🥜+/
// Нежадное (ленивое) регулярное выражение:
// Это белка, которая экономит свои силы: "Возьму только несколько, а остальное оставлю на зиму!"
/🥜+?/
Вставьте ?
, чтобы сконцентрировать регулярное выражение на наибыстрейшем совпадении.
Уточнение посредством конструкции "{n,m}" в регулярных выражениях
Когда нужна большая точность, составьте выражение вида {n,m}?
для определенного специального нежадного поиска:
let str = "123456789";
let greedyMatch = str.match(/\d{2,5}/);
let nonGreedyMatch = str.match(/\d{2,5}?/); // Более умеренный подход
console.log(greedyMatch[0]); // "12345"
console.log(nonGreedyMatch[0]); // "12"
Здесь жадное выражение \d{2,5}
пытается найти от двух до пяти цифр, в то время как нежадное \d{2,5}?
останавливается после второй цифры.
Применение владеющих квантификаторов
Если хотите исключить возможность отката при сценарии совпадений, владеющий квантификатор, такой как ++
или *+
, будет отличным решением:
let str = "12345!";
let greedyMatch = str.match(/\d*!/); // Некоторые цифры гуляют на всю катушку!
let possessiveMatch = str.match(/\d*+!/); // Здесь цифры не позволяют отката
console.log(greedyMatch[0]); // "12345!"
console.log(possessiveMatch); // null
Владеющее выражение \d*+!
не дает совпадений, поскольку не разрешает откатиться и найти !
.
Полезные материалы
- Квантификаторы в JavaScript | MDN
- Справочник по RegExp для JavaScript
- Руководство по квантификаторам в регулярных выражениях: жадные, ленивые, владеющие
- regex101: создание, тестирование и отладка регулярных выражений
- Производительность регулярных выражений
- 30-минутный курс по регулярным выражениям от CodeProject