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

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

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

<img\s.*>

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

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

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

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

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


person Pointer Null    schedule 10.08.2012    source источник
comment
На каком языке вы используете REGEX?   -  person Mitya    schedule 10.08.2012


Ответы (3)


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

Например,

<img\s.*?>

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

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

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

person Pavan Manjunath    schedule 10.08.2012
comment
Есть также уловка, которую вы можете использовать, чтобы обойти это: поскольку \ s означает любые пробелы, а \ S означает любые непробельные символы, [\ s \ S] будет соответствовать ЛЮБОМУ символу (например,, но включая новую строку)! Точно так же вы можете использовать [\ d \ D] или [\ w \ W]. Это может быть довольно удобный небольшой прием, и это, безусловно, очень полезный прием, о котором следует помнить. - person Tom Lord; 21.11.2014
comment
Или даже, в этом примере, вы можете использовать: <img[^>]*> для достижения того же эффекта: поскольку любой другой символ, кроме >, ДОЛЖЕН включать новую строку! - person Tom Lord; 21.11.2014
comment
хороший ответ, а как насчет баш? echo ‹img src = test› bla ‹img src = a› | grep -P '‹img \ s. *?›' соответствует всей строке, несмотря на? оператор. - person Thorsten Staerk; 22.03.2015
comment
@Thorsten: -P выбирает режим Perl, а perldoc говорит *? не жадный. Подтверждено, что работает на Linux 10-летней давности и на новейшем Linux. Возможно, вы неверно истолковали вывод. grep печатает любую строку (полностью), где где-то есть совпадение. Добавьте -o, чтобы печатать только совпадения. - person Joachim Wagner; 21.01.2016
comment
Я собираюсь найти образец в строке ниже. строка = /ab[1]. bc [2]. cd [3]; шаблон = ([a-zA-Z0-9]. *? \ [\\ d *? \]); Я могу найти несколько совпадений в TextFX, notepad ++, но в java он находит только одно совпадение - person Mrinal Bhattacharjee; 17.03.2016

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

Но помните, что весь набор HTML не может быть проанализирован с помощью регулярных выражений.

person Ilya    schedule 10.08.2012
comment
Ваш ответ напомнил об этом: stackoverflow.com/a/1732454/431 - person Mario Marinato; 11.11.2016
comment
Я думаю, более ясно будет сказать, что *? - это нежадная версия *. - person golopot; 12.11.2016

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

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

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

[^>]*

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

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

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

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

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

person tripleee    schedule 19.11.2018