Регулярные выражения в 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


