diferença entre .* e * na expressão regular

diferença entre .* e * na expressão regular

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 +( egrepapenas) não são nada por si só. Eles sempre se referem ao caractere/átomo anterior - se este é um caractere real (por exemplo, Lou 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 caractere
  • a..a- combina dois as com dois caracteres de qualquer tipo entre
  • .*- corresponde a 0, 1 ou mais ocorrências de qualquer caractere
  • B*- corresponde a 0, 1 ou mais ocorrências de "B"

informação relacionada