Для регулярных выражений часто желательно сделать часть выражения нежадной. Для этого мы используем знак вопроса.
В чем разница между (.*?)
а также (.*)?
когда используется как часть большего выражения, чтобы захватить ноль или более символов?
Например, будет: (.*?)ng
когда-либо дать другой результат, чем (.*)?ng
?
Конечные результаты одинаковы (подтверждено https://regex101.com/ ), но есть ли различия, которые не так очевидны?
angng
для тестовой строки в regex101 чтобы увидеть, как два выражения соответствуют различным частям строки.(.*)?ng
это правильное выражение. Это то, что я всегда использовал (и имеет больше смысла), но я читал книгу, которая использовала(.*?)ng
и это выглядело неправильно, но у меня были проблемы с тем, чтобы положить палец на Зачем , Ваш пример хорошо это иллюстрирует. Кроме случаев, когда завершающее выражение (ng
в этом примере) дублируется, можете ли вы вспомнить другие случаи, когда результаты будут другими?Ответы:
Как уже упоминалось в мой другой ответ ,
.*?
версия ленивая Это означает, что часть, заключенная в скобки, будет применяться как можно меньше, чтобы регулярное выражение совпадало. Версия с вопросительным знаком вне скобок является жадной: она будет применяться к как можно большему количеству символов.Оба выражения будут иметь одинаковый эффект, если вы посмотрите только на совпадение, а не на совпадение. Два подстановочных знака совпадут если возможно , но один минимизирует захваченное количество, в то время как другой максимизирует его. Они отличаются, однако, тем, что они захватывают.
Давайте посмотрим пример захвата различий:
singing
, Содержит буквальноеng
дважды. В(.*?)ng
,(.*?)
будет хватать все до первогоng
- как только он это видит, он готов: лень. Будет захватыватьsi
в этом случае.(.*)?ng
постараюсь поймать как можно больше - это жадный - оставив только финалng
из. Захватываетsingi
Вот.Если во входной строке не будет нескольких экземпляров детали вне шаблона, вы не увидите разницы.
источник