Как написать регулярное выражение, которое соответствует не жадным?

Мне нужна помощь в сравнении регулярных выражений с неживым вариантом.

Шаблон соответствия:

<img\s.*>

Соответствующий текст:

<html>
<img src="test">
abc
<img
  src="a" src='a' a=b>
</html>

Я тестирую http://regexpal.com

Это выражение соответствует всему тексту от <img до последнего >. Мне нужно, чтобы он совпал с первым встреченным > после начального <img, поэтому здесь мне нужно было бы получить два совпадения вместо того, которое я получаю.

Я пробовал все комбинации не жадных ?, без успеха.

Ответ 1

Нежелательный ? работает отлично. Просто вам нужно выбрать dot match all в механизмах регулярных выражений (regexpal, используемый вами движок, также имеет эту опцию), с которым вы тестируете. Это связано с тем, что при использовании . регулярные выражения обычно не соответствуют разрыву строк. Вам нужно явно указать им, что вы тоже хотите сопоставить строки с помощью .

Например,

<img\s.*?>

отлично работает!

Проверьте результаты здесь.

Кроме того, читайте как точка ведет себя в разных вариантах регулярных выражений.

Ответ 2

Оператор ? делает совпадение неживым. Например. .* жадный, а .*? - нет. Таким образом, вы можете использовать что-то вроде <img.*?> для соответствия всему тегу. Или <img[^>]*>.

Но помните, что весь набор HTML не может быть фактически обработан регулярными выражениями.

Ответ 3

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

Многие старые языки и редакторы поддерживают только традиционные регулярные выражения, в которых отсутствует механизм управления жадностью оператора повторения * - он всегда соответствует самой длинной из возможных строк.

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

[^>]*

который все еще соответствует как можно большему количеству чего-либо; но что-то - это не просто . "любой персонаж", а вместо этого "любой персонаж, который не >".

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

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

Например, регулярное выражение с конечным контекстом после подстановочного знака, такого как .*?><br/>, будет перепрыгивать через любой вложенный >, пока не найдет конечный контекст (здесь, ><br/>), даже если для этого требуется расстановка нескольких экземпляров > и символов новой строки если вы позволите, где [^>]*><br/>, очевидно, не может и не сделает этого.

Конечно, это все еще не то, что вам нужно, если вам нужно справиться с <img title="quoted string with > in it" src="other attributes"> and perhaps <img title="nested tags">, но в этот момент вам, наконец, следует отказаться от использования регулярного выражения для этого, как мы все вам говорили в первую очередь.

Ответ 4

Проверить вопрос о переполнении стека Что означают ленивые и жадные в контексте регулярных выражений?.

Жадный означает совпадение длинной строки.

Lazy означает совпадение кратчайшей строки.

Например, жадный h. + l соответствует "ад" в "привет", но ленивый h. +? l соответствует "hel".