Захватывает ноль или более символов в регулярном выражении, не будучи жадным

1

Для регулярных выражений часто желательно сделать часть выражения нежадной. Для этого мы используем знак вопроса.

В чем разница между (.*?) а также (.*)? когда используется как часть большего выражения, чтобы захватить ноль или более символов?

Например, будет: (.*?)ng когда-либо дать другой результат, чем (.*)?ng ?

Конечные результаты одинаковы (подтверждено https://regex101.com/ ), но есть ли различия, которые не так очевидны?

RockPaperLizard
источник
1
использование angng для тестовой строки в regex101 чтобы увидеть, как два выражения соответствуют различным частям строки.
creidhne
@creidhne Большое спасибо. Так (.*)?ng это правильное выражение. Это то, что я всегда использовал (и имеет больше смысла), но я читал книгу, которая использовала (.*?)ngи это выглядело неправильно, но у меня были проблемы с тем, чтобы положить палец на Зачем , Ваш пример хорошо это иллюстрирует. Кроме случаев, когда завершающее выражение ( ng в этом примере) дублируется, можете ли вы вспомнить другие случаи, когда результаты будут другими?
RockPaperLizard
1
Так ты собираешься замкнуть цикл и опубликовать ответ? :-) Кстати, первый вопрос появился в очереди на рецензию как обман этого вопроса (что удивительно, поскольку обычно вы не можете назвать вопрос в качестве основного, если на него нет ответа), но действие еще не получил ни одного голоса Связывать их было бы разумнее, если бы у этого был свой ответ.
fixer1234

Ответы:

0

Как уже упоминалось в мой другой ответ , .*? версия ленивая Это означает, что часть, заключенная в скобки, будет применяться как можно меньше, чтобы регулярное выражение совпадало. Версия с вопросительным знаком вне скобок является жадной: она будет применяться к как можно большему количеству символов.

Оба выражения будут иметь одинаковый эффект, если вы посмотрите только на совпадение, а не на совпадение. Два подстановочных знака совпадут если возможно , но один минимизирует захваченное количество, в то время как другой максимизирует его. Они отличаются, однако, тем, что они захватывают.

Давайте посмотрим пример захвата различий: singing, Содержит буквальное ng дважды. В (.*?)ng, (.*?) будет хватать все до первого ng - как только он это видит, он готов: лень. Будет захватывать si в этом случае. (.*)?ng постараюсь поймать как можно больше - это жадный - оставив только финал ng из. Захватывает singi Вот.

Если во входной строке не будет нескольких экземпляров детали вне шаблона, вы не увидите разницы.

Ben N
источник