Я ответил на этот вопрос в SuperUser, который имел отношение к виду регулярных выражений, используемых при подборе вывода.
Ответ, который я дал, был таков:
tail -f log | grep "some_string.*some_string"
И затем, в трех комментариях к моему ответу @Bob написал это:
.*
жадный и может захватить больше, чем вы хотите..*?
обычно лучше.
Тогда это,
?
является модификатором на*
, что делает его ленивым вместо жадного по умолчанию. Предполагая PCRE.
Я гуглил PCRE
, но не мог понять, каково значение этого в моем ответе?
и наконец это,
Я также должен отметить, что это регулярное выражение (по умолчанию grep делает регулярное выражение POSIX), а не глобус оболочки.
Я знаю только, что такое Regex и как его использовать в команде grep. Итак, я не смог получить ни одного из этих 3 комментариев, и у меня есть следующие вопросы:
- Каковы различия в использовании
.*?
против.*
? - Что лучше и при каких обстоятельствах? Пожалуйста, приведите примеры.
Также было бы полезно понять комментарии, если кто-то мог
ОБНОВЛЕНИЕ: Как ответ на вопрос Чем Regex отличается от Shell Globs? @Kusalananda предоставил эту ссылку в своем комментарии.
ПРИМЕЧАНИЕ: При необходимости, пожалуйста, прочитайте мой ответ на этот вопрос, прежде чем отвечать для ссылки на контекст.
источник
.*
сравнении.*?
вопроса. Вопрос «Разница между регулярными выражениями и глобусами оболочки» уже обсуждался на этом сайте.Ответы:
Ашок уже указал на разницу между
.*
и.*?
, поэтому я просто предоставлю некоторую дополнительную информацию.grep
(предполагается версия GNU) поддерживает 4 способа сопоставления строк:grep
по умолчанию использует BRE.BRE и ERE описаны в главе о регулярных выражениях POSIX, а PCRE - на официальном веб-сайте . Обратите внимание, что функции и синтаксис могут различаться в разных реализациях.
Стоит сказать, что ни BRE, ни ERE не поддерживают лень :
Так что если вы хотите использовать эту функцию, вам нужно будет использовать вместо этого PCRE:
Редактировать 1
.*
используется для соответствия «самой длинной» 1 модели..*?
используется для соответствия «кратчайшему» 1 шаблону.По моему опыту, наиболее желаемое поведение - обычно второе.
Например, допустим, у нас есть следующая строка, и мы хотим соответствовать только HTML-тегам 2 , а не содержимому между ними:
Теперь сравните
.*
против.*?
:1. Значение «самый длинный» и «самый короткий» в контексте регулярных выражений, как указал Кусалананда, немного сложнее . Обратитесь к официальной документации для получения дополнительной информации.
2. Не рекомендуется разбирать html с регулярным выражением . Это просто пример для образовательных целей, не используйте его в производстве.
источник
.*
против.*?
?Предположим, я беру строку вроде:
can cats eat plants?
Использование жадного алгоритма
c.*s
будет соответствовать всей строке, так как она начинаетсяc
и заканчиваетсяs
, будучи жадным оператором, она продолжает совпадать до последнего появления s.Принимая во внимание, что использование ленивых
c.*?s
будет соответствовать только до тех пор, пока неs
будет найдено первое вхождение , то есть строкаcan cats
.Из приведенного выше примера вы можете получить следующее:
«Жадность» означает соответствие самой длинной возможной строки. «Ленивый» означает соответствие самой короткой возможной строки. Добавление
?
к квантору , как*
,+
,?
или{n,m}
делают его ленивым.источник
cats
, поэтому он не применяет строго кратчайший в этом смысле.Строка может быть сопоставлена несколькими способами (от простого до более сложного):
В качестве статической строки (предположим, var = 'Hello World!'):
shell
[ "$var" = "Hello World!" ] && echo yes
grep
echo "$var" | grep -F "Hello"
bash
grep -F "Hello" <<<"$var"
Как шар:
shell
echo ./*
# список всех файлов в pwd.
оболочки
case $var in (*Worl*) echo yes;; (*) echo no;; esac
Баш
[[ "$var" == *"Worl"* ]] && echo yes
Есть основные и расширенные шары. В
case
примере используются основные глобусы. В[[
примере с bash используются расширенные глобусы. Первое совпадение файла может быть базовым или расширенным в некоторой оболочке, например,extglob
в bash. Оба идентичны в этом случае. Grep не мог использовать шарики.Звездочка в глобе означает нечто иное, чем звездочка в регулярном выражении :
Glob
* matches any number (including none) of
любые символы .регулярное выражение
* matches any number (including none) of the
предыдущего элемента .В качестве основного регулярного выражения (BRE):
sed
echo "$var" | sed 's/W.*d//'
# print: Привет!
grep
grep -o 'W.*d' <<<"$var"
# print World!
В базовых оболочках или в awk нет BRE.
Расширенные регулярные выражения (ERE):
bash
[[ "$var" =~ (H.*l) ]]
# match: Hello Worl
sed
echo "$var" | sed -E 's/(d|o)//g'
# print: Hell Wrl!
awk
awk '/W.*d/{print $1}' <<<"$var"
# print: Здравствуйте,
grep
grep -oE 'H.*l' <<<"$var"
# print: Здравствуйте, Worl
Perl-совместимые регулярные выражения:
grep
grep -oP 'H.*?l
# print: Hel
Только в PCRE
*?
есть определенный синтаксический смысл.Это делает звездочку леиво (ungreedy): Лень Вместо жадности .
Это только верхушка айсберга, там есть жадный, ленивый , послушный или притяжательный . Есть также заглядывание вперед и назад, но они не относятся к звездочке
*
.Есть альтернатива, чтобы получить тот же эффект, что и не жадное регулярное выражение:
Идея очень проста: не используйте точку
.
, отмените следующий символ для соответствия[^o]
. С веб-тегом:Выше следует полностью уточнить все комментарии @Bob 3. Перефразируя:
.*
жадный.*?
нет.Вопросов
Каковы различия в использовании. ? против ?
.*?
действителен только в синтаксисе PCRE..*
более портативный.[^a]*
Что лучше и при каких обстоятельствах? Пожалуйста, приведите примеры.
Лучше? Это зависит от цели. Нет лучше, каждый полезен для разных целей. Я привел несколько примеров выше. Вам нужно больше?
источник