Как сделать не-жадный матч в grep?

Я хочу, чтобы grep самое короткое совпадение, и шаблон должен выглядеть примерно так:

<car ... model=BMW ...>
...
...
...
</car>

... означает любой символ, а вход - несколько строк.

Ответ 1

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

По умолчанию grep не поддерживает нежелательные модификаторы, но вы можете использовать grep -P для использования синтаксиса Perl.

Ответ 2

Фактически .*? работает только в perl. Я не уверен, какой эквивалентный синтаксис расширенного регулярного выражения grep будет. К счастью, вы можете использовать синтаксис perl с grep, поэтому grep -P будет работать, но grep -E, который будет таким же, как egrep, не будет работать (это было бы жадно).

Смотрите также: http://blog.vinceliu.com/2008/02/non-greedy-regular-expression-matching.html

Ответ 3

Мой grep, который работает после тестирования материала в этом потоке:

echo "hi how are you " | grep -shoP ".*? "

Просто убедитесь, что вы добавили пробел к каждой из ваших линий

(Mine был строковым поиском, чтобы выплескивать слова)

Ответ 4

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

Например, чтобы извлечь все ссылки на jpeg файлы из содержимого страницы, вы должны использовать:

grep -o '"[^" ]\+.jpg"'

Ответ 5

В коротком ответе используется следующее регулярное выражение:

(?s)<car .*? model=BMW .*?>.*?</car>
  • (? s) - это делает соответствие между многострочными
  • . *? - соответствует любому символу, несколько раз ленивым способом (минимальный матч)

A (немного) более сложный ответ:

(?s)<([a-z\-_0-9]+?) .*? model=BMW .*?>.*?</\1>

Это позволит сопоставить car1 и car2 в следующем тексте

<car1 ... model=BMW ...>
...
...
...
</car1>
<car2 ... model=BMW ...>
...
...
...
</car2>
  • (..) представляет группу захвата
  • \1 в этом контексте соответствует sametext, как это было в последнее время согласовано группа захвата № 1