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

5

Eu tenho um arquivo chamado "test" que contém

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

agora, quando eu uso grep '\<l.*x\>' , corresponde a:

linux
it's linux
l...x

mas quando eu uso grep '\<l*x\>' , ele corresponde apenas a:

l...x , mas de acordo com o guia de referência, Ao usar *, o item anterior será correspondido a 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 eu entendi errado?

    
por ravi 21.04.2013 / 13:15

3 respostas

10

notação (. *)

O * nas expressões regulares. * e * refere-se a uma contagem, não a caracteres por palavra, mais exatamente significa 'zero ou mais' . Além disso, o . significa 'qualquer caractere único' .

Então, quando você os coloca juntos, você obtém 'zero ou mais caracteres' . Por exemplo, strings como estas:

  • linux
  • linnnnnx
  • lnx
  • oi linux
  • lx

Seria correspondido por <l.*x> . O último é importante, mostra que o . * também não combina com nada.

notação (*)

O uso de * sozinho como eu disse é um contador. Então, quando você o coloca após uma letra como 'l' , o * está dizendo 'zero ou mais de l' .

Observe se nós recebemos l*x , isso corresponderá a l...x , mas provavelmente não pelo motivo que você pensa.

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

Ele está combinando no "x" à direita. O 'l' não tem nada a ver com o porque isso está sendo correspondido, além do fato de que o 'x' é precedido por 'zero ou mais l's' .

    
por 21.04.2013 / 13:52
1

Se você quisesse combinar qualquer coisa começando com "l" e terminando com "x", tente a expressão regular "l. * x". Aqui "." e "*" são caracteres especiais representando um único caractere válido e caracteres de pelo menos comprimento zero, respectivamente. Aqui, o que precede "*" é um ".", Então o que vier no lugar de "." é repetido de acordo com a definição "*", conforme acima.

    
por 21.04.2013 / 13:49
1

Para o shell (por exemplo, bash) quando os jokers são usados para corresponder nomes de arquivos, * e ? são os próprios caracteres - eles representam o (s) caractere (s).

Para a expressão regular, por outro lado, * , ? , {n,m} (intervalo de ocorrências) e + ( egrep only) não são nada por si mesmos. Eles sempre se referem ao caractere / átomo anterior - tempo este é um caractere real (por exemplo, L ou 5 ), o . (coringa) que pode representar qualquer caractere, um intervalo de caracteres (por exemplo, [a-f] ) ou um padrão de vários caracteres (egrep apenas; por exemplo, (abba) - onde "abba" é considerado uma unidade). Os * e ? , portanto, não representam nada por si mesmos, mas dizem algo sobre quantas vezes o personagem anterior (que pode ser um palhaço para qualquer um ou um grupo tratado como uma unidade) deve ser repetido.

Depois de se lembrar dessa distinção, entre o modo como o shell e o regex usam o * e o ? , ele deve se encaixar.

Assim, para regex:

  • . - representa exatamente uma ocorrência de qualquer caractere
  • a..a - corresponde a dois a's 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"
por 21.04.2013 / 15:48