Відповіді:
Ви шукаєте не жадібну (або ліниву) відповідність. Щоб отримати не жадібну відповідність у регулярних виразах, вам потрібно використовувати модифікатор ?
після кількісного показника. Наприклад, ви можете змінити .*
на .*?
.
За замовчуванням grep
не підтримує не жадібних модифікаторів, але ви можете використовувати grep -P
синтаксис Perl.
.
відповідати новим рядкам, називається DOTALL або однорядковий режим; Рубі - це єдиний, хто називає це багаторядковим . В інших ароматах багатолінійний режим - це режим, який дозволяє якорям ( ^
і $
) збігатися на межі лінії. У Ruby немає еквівалентного режиму, оскільки в Ruby вони завжди працюють так.
-P
була абсолютно новою для мене, я щасливо поздоровився роками, і лише використовую -E
... стільки даремно витрачених років! - Примітка до самоврядування: перечитайте сторінки Man як (навіть більше!) Звичайну річ, ви ніколи не перетравлюєте достатню кількість перемикачів та параметрів.
grep
не підтримується -P
, але якщо ви використовуєте, egrep
ви можете використовувати .*?
шаблон для досягнення того ж результату. egrep -o 'start.*?end' text.html
-P
але зате -E
закликає, egrep
отже, запропоноване .*?
працює просто чудово.
Насправді .*?
єдині роботи в Росії perl
. Я не впевнений, яким би був еквівалентний синтаксис розширеного regexp grep. На щастя, ви можете використовувати синтаксис perl з grep, щоб grep -P
це спрацювало, але grep -E
це те саме, egrep
що не було б (було б жадібно).
Дивіться також: http://blog.vinceliu.com/2008/02/non-greedy-regular-expression-matching.html
grep -P
не працює в GNU grep 2.9 - просто спробував це (він не помиляється, просто мовчки не застосовує ?
. Інтертестно також не клас, наприклад:env|grep '[^\=]*\='
grep -P
варіантів чи pgrep
команд, але це egrep
чудово.
pgrep
моєму вікні OS X 10.9 є команда, але це зовсім інша програма, мета якої - "пошук або подання сигналів процесів по імені".
Мій греп, який працює після випробування матеріалів у цій темі:
echo "hi how are you " | grep -shoP ".*? "
Просто переконайтеся, що ви додали пробіл до кожного свого рядка
(Моя була рядок за рядком пошуку, щоб виплюнути слова)
-shoP
приємний мнемонік :)
echo "bbbbb" | grep -shoP 'b.*?b'
це трохи досвіду навчання. Єдине, що працювало для мене і з точки зору явно лінивого.
grep
Для не жадібного матчу grep
ви можете використовувати заперечений клас персонажів. Іншими словами, намагайтеся уникати макіяжів.
Наприклад, щоб отримати всі посилання на файли jpeg із вмісту сторінки, ви використовуєте:
grep -o '"[^" ]\+.jpg"'
Щоб мати справу з декількома лініями, xargs
спочатку подайте вхід . Для продуктивності використовуйте ripgrep
.
Коротка відповідь використовує наступний регулярний вираз:
(?s)<car .*? model=BMW .*?>.*?</car>
(Трохи) більш складна відповідь:
(?s)<([a-z\-_0-9]+?) .*? model=BMW .*?>.*?</\1>
Це дозволить співставити car1 та car2 у наступному тексті
<car1 ... model=BMW ...>
...
...
...
</car1>
<car2 ... model=BMW ...>
...
...
...
</car2>
Вибачте, що я запізнююсь на 9 років, але це може допомогти глядачам у 2020 році.
Отже, припустимо, у вас є така лінія "Hello my name is Jello"
. Тепер ви хочете знайти слова, які починаються з 'H'
і закінчуються 'o'
, з будь-якою кількістю символів між ними. І ми не хочемо рядків, ми просто хочемо слова. Тож для цього ми можемо використовувати вираз:
grep "H[^ ]*o" file
Це поверне всі слова. Це працює так: Це дозволить усім символам замість символів пробілу посередині, таким чином ми зможемо уникнути кількох слів в одному рядку.
Тепер ви можете замінити пробільний символ будь-яким іншим символом, який ви хочете. Припустимо, початковий рядок був "Hello-my-name-is-Jello"
, тоді ви можете отримати слова, використовуючи вираз:
grep "H[^-]*o" file
Я знаю, що це трохи мертвий пост, але я просто помітив, що це працює. Це видалило і очищення, і очищення з мого результату.
> grep -v -e 'clean\-\?up'
> grep --version grep (GNU grep) 2.20