
У меня есть файл с именем "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}
+
egrep
L
5
.
[a-f]
(abba)
*
?
Как только вы запомните это различие между тем, как оболочка и регулярное выражение используют *
и ?
, все станет на свои места.
Итак, для регулярного выражения:
.
- представляют ровно одно появление любого символаa..a
- соответствует двум буквам «a» с двумя любыми символами между ними.*
- соответствует 0, 1 или более вхождений любого символаB*
- соответствует 0, 1 или более вхождений «B»