
Eu tenho um arquivo chamado "test" que contém
linux
Unixlinux
Linuxunix
it's linux
l...x
agora quando eu uso grep '\<l.*x\>'
, ele corresponde:
linux
it's linux
l...x
mas quando eu uso grep '\<l*x\>'
, ele corresponde apenas:
l...x
, mas de acordo com o guia de referência, ao usar * , o item anterior será correspondido zero ou mais vezes, ou seja, deve corresponder a qualquer coisa que comece com 'l' e termine com 'x'
Alguém pode explicar por que não está mostrando o resultado desejado ou se entendi errado?
Responder1
notação (.*)
O * nas expressões regulares .* e * refere-se a uma contagem, não a caracteres propriamente ditos, mais exatamente significa'zero ou mais'. Além disso, o.significa'qualquer caractere único'.
Então, quando você os junta, você obtém'zero ou mais de qualquer caractere'. Por exemplo, strings como estas:
- linux
- linnnnnx
- lnx
- oi linux
- lx
Seria correspondido por <l.*x>
. O último é importante, pois mostra que o.*não pode corresponder a nada também.
notação (*)
O uso de * sozinho como eu disse é um contador. Então, quando você coloca depois de uma carta como'eu'o * está dizendo'zero ou mais de l'.
Observe que se usarmos o grep para l*x
, isso corresponderá l...x
, mas provavelmente não pelo motivo que você imagina.
% echo "l...x" | grep "l*x"
l...x
Está combinando no 'x' final. O 'l' não tem nada a ver com o motivo da correspondência, exceto o fato de que o 'x' é precedido por'zero ou mais l's'.
Responder2
Se você quiser corresponder qualquer coisa que comece com "l" e termine em "x", tente a expressão regular "l.*x". Aqui "." e "*" são caracteres especiais que representam um único caractere válido e caracteres de comprimento pelo menos zero, respectivamente. Aqui o que precede "*" é um ".", então o que quer que venha no lugar de "." é repetido de acordo com a definição de "*" conforme acima.
Responder3
Para o shell (por exemplo, bash), quando jokers são usados para combinar nomes de arquivos *
e ?
são os próprios personagens - eles representam o(s) personagem(s).
Por outro lado, para expressões regulares, *
, ?
, {n,m}
(intervalo de ocorrências) e +
( egrep
apenas) não são nada por si só. Eles sempre se referem ao caractere/átomo anterior - se este é um caractere real (por exemplo, L
ou 5
), o .
(curinga) que pode representar qualquer caractere, um intervalo de caracteres (por exemplo, [a-f]
) ou um padrão de vários caracteres (somente egrep; por exemplo (abba)
- onde “abba” é considerado uma unidade). Os *
e, ?
portanto, não representam nada por si só, mas dizem algo sobre quantas vezes o caractere anterior (que pode ser um curinga para qualquer um ou um grupo tratado como uma unidade) deve ser repetido.
Depois que você se lembrar dessa distinção, entre a maneira como o shell e o regex usam o *
e ?
, ela deverá se encaixar.
Então, para regex:
.
- representa exatamente uma ocorrência de qualquer caracterea..a
- combina dois as com dois caracteres de qualquer tipo entre.*
- corresponde a 0, 1 ou mais ocorrências de qualquer caractereB*
- corresponde a 0, 1 ou mais ocorrências de "B"