Может ли кто-нибудь объяснить эти два термина понятным способом?
regex
regex-greedy
non-greedy
ajsie
источник
источник
Ответы:
Жадный будет потреблять как можно больше. Из http://www.regular-expressions.info/repeat.html мы видим пример попытки сопоставить теги HTML с
<.+>
. Предположим, у вас есть следующее:Вы можете подумать, что
<.+>
(.
означает, что любой символ, не являющийся символом новой строки и+
означает один или несколько ), будет соответствовать только символ «<em>
и»</em>
, когда в действительности он будет очень жадным, и переходить от первого<
к последнему>
. Это означает, что он будет соответствовать<em>Hello World</em>
вместо того, что вы хотели.Сделать это ленивым (
<.+?>
) предотвратит это. Добавляя?
после+
, мы говорим, чтобы повторить как можно меньше раз , поэтому первый>
мы сталкиваемся, - это то, где мы хотим остановить сопоставление.Я рекомендую вам загрузить RegExr , отличный инструмент, который поможет вам изучить регулярные выражения - я использую его постоянно.
источник
<[^>]+>
regex101.com/r/lW0cY6/1«Жадность» означает соответствие самой длинной строки.
«Ленивый» означает соответствие самой короткой возможной строки.
Например, жадные
h.+l
матчи'hell'
в'hello'
но ленивыеh.+?l
матчи'hel'
.источник
h.+l
матчи'helol'
в'helolo'
но ленивыеh.+?l
матчи'hel'
.x?
Означает, чтоx
это необязательно, но+?
другой синтаксис. Это значит перестать смотреть после того, как вы найдете что-то подходящее - ленивое соответствие.?
означает необязательный и+?
означает ленивый. Поэтому\+?
средство+
необязательно.Пример:
тестовая строка: stackoverflow
выражение жадного выражения :
s.*o
output: stackoverflo wвыражение lazy reg :
s.*?o
output: верфи стекаисточник
re.match('(f)?(.*)', 'food').groups()
сre.match('(f)??(.*)', 'food').groups()
. В последнем(f)??
случае не будет совпадать с лидирующим 'f', хотя это может быть. Следовательно, 'f' будет соответствовать второй группе захвата '. *'. Я уверен, что вы можете создать пример с помощью '{n}?' тоже. По общему признанию, эти два очень редко используются.Жадный означает, что ваше выражение будет соответствовать как можно большей группе, ленивый означает, что оно будет соответствовать наименьшей возможной группе. Для этой строки:
и это выражение:
Жадное совпадение будет соответствовать всей строке, а ленивое совпадение - только первой
abc
.источник
Насколько я знаю, большинство движков регулярных выражений по умолчанию жадные. Добавление знака вопроса в конце квантификатора позволит включить ленивое совпадение.
Как отметил @Andre S в комментарии.
Обратитесь к примеру ниже, чтобы узнать, что является жадным, а что ленивым.
Результат:
источник
Взято с www.regular-expressions.info
Жадность : Жадные кванторы сначала пытается повторить маркер столько раз , сколько возможно, и постепенно отдает матчи как на откатывается двигателя , чтобы найти общий матч.
Ленивость : Ленивый квантификатор сначала повторяет токен столько раз, сколько требуется, и постепенно расширяет совпадение, когда двигатель откатывается через регулярное выражение, чтобы найти общее совпадение.
источник
Из регулярного выражения
источник
Жадное совпадение. Поведение регулярных выражений по умолчанию должно быть жадным. Это означает, что он пытается извлечь как можно больше, пока не будет соответствовать шаблону, даже если меньшая часть была бы синтаксически достаточной.
Пример:
Вместо сопоставления до первого вхождения '>' он извлекал всю строку. Это стандартное поведение regex или «возьми все».
Ленивое сопоставление , с другой стороны, «занимает как можно меньше». Это может быть достигнуто путем добавления
?
в конце шаблона.Пример:
Если вы хотите получить только первое совпадение, используйте вместо этого метод поиска.
Источник: Python Regex Примеры
источник
Жадность означает, что она будет поглощать ваш паттерн до тех пор, пока не останется ни одного из них, и она не сможет смотреть дальше.
Ленивый остановится, как только встретит первый шаблон, который вы запросили.
Одним из распространенных примеров, с которыми я часто сталкиваюсь, является
\s*-\s*?
регулярное выражение([0-9]{2}\s*-\s*?[0-9]{7})
Первый
\s*
классифицируется как жадный из-за того, что*
после того, как встретятся цифры, он будет искать как можно больше пробелов, а затем будет искать тире "-". Где, поскольку второй\s*?
ленив из-за настоящего,*?
это означает, что он будет смотреть первый символ пробела и остановится прямо там.источник
Лучше всего показывает пример. Строка.
192.168.1.1
и жадное регулярное выражение.\b.+\b
Вы можете подумать, что это даст вам 1-й октет, но на самом деле соответствует целой строке. Почему? Потому что. + Является жадным, и жадное совпадение соответствует каждому символу,192.168.1.1
пока не достигнет конца строки. Это важный бит! Теперь он начинает возвращать по одному символу за раз, пока не найдет совпадение для 3-го токена (\b
).Если в начале строки был текстовый файл объемом 4 ГБ и 192.168.1.1, вы могли легко увидеть, как это может вызвать проблему с возвратом.
Чтобы сделать регулярное выражение не жадным (ленивым), поставьте знак вопроса после своего жадного поиска, например
Теперь происходит то, что токен 2 (
+?
) находит совпадение, регулярное выражение перемещается по персонажу и затем пытается использовать следующий токен (\b
) вместо токена 2 (+?
). Так что ползет осторожно.источник
Жадные квантификаторы похожи на IRS / ATO: они берут столько, сколько могут:
Если он там, они придут и возьмут его. Они возьмут все это
Например, IRS совпадает с этим регулярным выражением:
.*
$50,000
- IRS возьмет все это. Этот жадный.*{4}?
ERSСмотрите здесь для примера: regexr.com/4t27f
Нежадные квантификаторы - они берут как можно меньше
С другой стороны, если я запрашиваю возврат налога, IRS внезапно становится не жадным, и они используют этот квантификатор:
(.{2}?)([0-9]*)
против этого выражения:$50,000
первая группа не нуждающаяся и только соответствует$5
- так что я получаю$5
возмещение. Остальное забрало дядя Сэм, чтобы потратить их впустую.Смотрите здесь: Non-жадный пример .
Зачем беспокоиться?
Это становится важным, если вы пытаетесь сопоставить определенные части выражения. Иногда вы не хотите соответствовать всему.
источник
попытаться понять следующее поведение:
источник