разница между .* и * в регулярном выражении

разница между .* и * в регулярном выражении

У меня есть файл с именем "test", который содержит

linux
Unixlinux
Linuxunix
it's linux
l...x

теперь, когда я использую grep '\<l.*x\>', это соответствует:

linux
it's linux
l...x

но когда я использую grep '\<l*x\>', он соответствует только:

l...x, но согласно справочнику, при использовании * предыдущий элемент будет сопоставляться ноль или более раз, т.е. он должен соответствовать всему, что начинается с «l» и заканчивается на «x».

Может ли кто-нибудь объяснить, почему не отображается желаемый результат, или я неправильно понял?

решение1

обозначение (.*)

Символ * в регулярных выражениях .* и * относится к количеству, а не к количеству символов, точнее это означает«ноль или больше». Кроме того,.означает'любой отдельный символ'.

Итак, когда вы их соедините, вы получите«ноль или более любых символов». Например, такие строки:

  • линукс
  • линнннкс
  • lnx
  • привет линукс
  • лк

Будет соответствовать <l.*x>. Последнее важно, оно показывает, что.*тоже не может сравниться ни с чем.

обозначение (*)

Использование * в одиночку, как я уже сказал, является счетчиком. Поэтому, когда вы ставите его после буквы, например'л'* говорит«ноль или больше l».

Обратите внимание, если мы выполним grep для l*x, то это будет соответствовать l...x, но, вероятно, не по той причине, о которой вы подумали.

% echo "l...x" | grep "l*x"
l...x

Это сопоставление по завершающему 'x'. 'l' не имеет никакого отношения к тому, почему это сопоставляется, за исключением того факта, что 'x' предшествует«ноль или более l».

решение2

Если вы хотите найти что-либо, начинающееся с "l" и заканчивающееся на "x", попробуйте регулярное выражение "l.*x". Здесь "." и "*" — специальные символы, представляющие один допустимый символ и символы не менее нулевой длины соответственно. Здесь то, что предшествует "*", — это ".", поэтому все, что находится на месте "." повторяется в соответствии с определением "*" , как указано выше.

решение3

Для оболочки (например, bash), когда джокеры используются для сопоставления имен файлов *и ?являются самими символами, они представляют символ(ы).

С другой стороны, для регулярного выражения , , *( диапазон вхождений) и ( только) сами по себе ничего не представляют. Они всегда ссылаются на предыдущий символ/атом — будь то фактический символ (например, или ), (джокер), который может представлять любой символ, диапазон символов (например, ) или шаблон из нескольких символов (только egrep; например , где "abba" считается единицей). Таким образом, и сами по себе ничего не представляют, но сообщают что-то о том, сколько раз должен быть повторен предыдущий символ (который может быть джокером для любого или группы, рассматриваемой как единица).?{n,m}+egrepL5.[a-f](abba)*?

Как только вы запомните это различие между тем, как оболочка и регулярное выражение используют *и ?, все станет на свои места.

Итак, для регулярного выражения:

  • .- представляют ровно одно появление любого символа
  • a..a- соответствует двум буквам «a» с двумя любыми символами между ними
  • .*- соответствует 0, 1 или более вхождений любого символа
  • B*- соответствует 0, 1 или более вхождений «B»

Связанный контент