Diferença entre '.' '?' e '*' em expressões regulares?

15

Posso obter um exemplo de como esses três elementos (chamados metacaracteres?) diferem?

Eu sei que * significa tudo ou nada, mas não tenho certeza se é o jeito certo de pensar sobre isso. Por outro lado, . e ? parecem iguais. Eles combinam com um personagem, certo?

    
por posixKing 09.09.2016 / 04:43

3 respostas

12

Retirado diretamente da Wikipédia :

  

? O ponto de interrogação indica zero ou uma ocorrência do precedente   elemento. Por exemplo, colou? R corresponde tanto "cor" e "cor".

     

* O asterisco indica zero ou mais ocorrências do elemento anterior. Por exemplo, ab * c corresponde a "ac", "abc", "abbc", "abbbc" e   assim por diante.

A grande diferença é que o asterisco corresponde a zero ou mais ocorrências, enquanto o ponto de interrogação corresponde a zero ou uma ocorrência. Compare estes dois exemplos:

$ printf "colour\ncolor\ncolouur\n" | egrep 'colou?r'                          
colour
color
$ printf "colour\ncolor\ncolouur\n" | egrep 'colou*r'                          
colour
color
colouur

Como em colouur a letra u (o elemento anterior antes do qualificador ? ) ocorreu mais de uma vez, ela não corresponde a ? , mas corresponde a *

Exemplo semelhante:

$ printf "error\neror\ner\n" | egrep 'er?or'                                   
eror
$ printf "error\neror\ner\n" | egrep 'er*or'                                   
error
eror

Da mesma página da Wikipédia:

  

Corresponde a qualquer caractere único (muitos aplicativos excluem novas linhas e   exatamente quais caracteres são considerados novas linhas é sabor   codificação de caracteres e específico da plataforma, mas é seguro assumir   que o caractere de alimentação de linha está incluído). Dentro do suporte POSIX   expressões, o caractere de ponto corresponde a um ponto literal. Por exemplo, a.c   corresponde a "abc", etc., mas [a.c] corresponde apenas a "a", "." ou "c".

No nosso exemplo,

$ printf "colour\ncolor\ncolouur\n" | egrep 'colo.r'                           
colour
$ printf "colour\ncolor\ncolouur\n" | egrep 'colou.r'                          
colouur

Apropriadamente, o último é lido como match any line that has "colou", plus any character, plus letter "r"

Conclusão

Você perguntou: "Eu sei que '*' significa tudo ou nada, mas não tenho certeza se é o jeito certo de pensar sobre isso. Do outro '.' & amp; '?' parece mesmo ". Como você pode ver, o ponto e o asterisco não são exatamente os mesmos. O ponto opera em qualquer caractere que possa ocupar essa posição específica, enquanto o ponto de interrogação opera no elemento precedente.

    
por Sergiy Kolodyazhnyy 09.09.2016 / 05:26
30

Você pode estar confundindo expressões regulares com shell globs

Na sintaxe da expressão regular . representa qualquer caractere único (geralmente excluindo o caractere de nova linha), enquanto * é um quantificador que significa zero ou mais do átomo de regex anterior (caractere ou grupo) . ? é um quantificador que significa zero ou uma instância do átomo anterior, ou (em variantes de regex que a suportam) um modificador que define o comportamento do quantificador como não ganancioso .

Em globs de shell, ? representa um único caractere (como . do regex), enquanto * representa uma seqüência de zero ou mais caracteres (equivalente a regex .* ).

Algumas referências que você pode achar úteis são link e link

    
por steeldriver 09.09.2016 / 04:59
5

Nota: Examples provided are in Python. Embora o conceito permaneça o mesmo.

'.' é um símbolo correspondente que corresponde a qualquer caracter exceto caractere de nova linha (isso também pode ser substituído pelo argumento re.DOTALL em Python). Por isso, também é chamado de Wildcard .

'*' é um quantificador (define com que frequência um elemento pode ocorrer). É a abreviação de {0}} .

Significa “igualar zero ou mais” - o grupo que precede a estrela pode ocorrer qualquer número de vezes no texto. Pode ser completamente ausente ou repetido várias vezes.

'?' também é um quantificador . É a abreviação de {0,1} .

Significa "Corresponde a zero ou a um do grupo que precede este ponto de interrogação." Também pode ser interpretado como a parte que precede o ponto de interrogação é opcional .

por exemplo:

pattern = re.compile(r'(\d{2}-)?\d{10}')
mobile1 = pattern.search('My number is 91-9999988888')
mobile1.group()
Output: '91-9999988888'

mobile2 = pattern.search('My number is 9999988888')
mobile2.group()
Output: '9999988888'

No exemplo acima, '?' indica que os dois dígitos anteriores são opcionais. Eles podem não ocorrer ou ocorrer no máximo uma vez.

Diferença entre '.' e '?':

'.' corresponde / aceita / verifica qualquer caractere único para o local em que está mantendo a expressão regular.

por exemplo:

pattern = re.compile(r'.ot')
pattern.findall('dot will identify both hot and got.')
Output: ['dot', 'hot', 'got']

'?' corresponde / verifica a ocorrência zero ou única do grupo que a precede .

Verifique o exemplo do número de celular.

O mesmo acontece com '*' . Ele irá verificar zero ou mais ocorrências do grupo que o precede .

Combinação:

'.*' : Aceita quantas sequências forem disponibilizadas. Abordagem gananciosa .

'.*? 'Aceita a primeira sequência correspondente e pára. Abordagem não-gananciosa

Para mais informações, considere a leitura após duas perguntas ...

  • Como posso escrever um regex que corresponda a não ganancioso?
  • regex - O que fazer preguiçoso e ganancioso significa no contexto de expressões regulares?
por Dhaval Simaria 09.09.2016 / 10:11

Tags