[Prévia] [Próxima] [Prévia por assunto] [Próxima por assunto]
[Índice cronológico]
[Índice de assunto]
Re: NÃO Funciona!!! (Re: Ainda expressões regulares...)
- Subject: Re: NÃO Funciona!!! (Re: Ainda expressões regulares...)
- From: Nelson Posse Lago <lago@that.com.br>
- Date: Tue, 25 Jun 2002 02:08:40 -0300
On Mon, Jun 24 2002 at 07:36:01pm -0300, Juliana Barby Simão wrote:
> > 2.Reconheça cadeias cujas vogais estejam em ordem.
> >
> > ([^aeiou]*a)*([^aeiou]*e)*([^aeiou]*i)*([^aeiou]*o)*([^aeiou]*u)*[^aeiou]*
>
> Eu tentei executar mas não funcionou...
> A palavra "UVA" casou com o padrão, por exemplo....
>
> Eu já havia tentado algo do tipo e tb não tinha obtido sucesso... :-(
> Afinal, todos os padrões devem ocorrer ZERO ou mais vezes... Sendo q o ZERO
> sempre acontece...
Bom, em primeiro lugar, a palavra UVA casa com esse padrao porque esta' em
maiusculas e normalmente as regexes sao sensiveis `a caixa; assim, essa
regex enxerga a palavra UVA como uma palavra sem vogais e, portanto, com
as vogais em ordem (todas as "consoantes" casam com a ultima parte da
regex, [^aeiou]*).
Por outro lado, a palavra "uva" *nao* casa com esse padrao. Mas se voce
tentar:
echo "uva" | egrep '([^aeiou]*a)*([^aeiou]*e)*([^aeiou]*i)*([^aeiou]*o)*([^aeiou]*u)*[^aeiou]*'
Vai obter:
=>uva
Por que? Porque existe um pedaco dessa linha que casa com o padrao. Esse
e' um ponto importante de se pensar ao usar o grep: se um pedaco de uma
linha casa com a expressao regular dada, ele retorna a linha inteira.
Quando voce faz coisas do tipo "grep '^From: '
/var/spool/mail/mailbox", esse e' o comportamento que voce espera do grep;
mas quando a sua regex fica mais complexa, voce acaba imaginando que o
grep vai retornar apenas o que casa com o padrao. Entao lembre-se, ele
retorna a linha que contem o padrao, nao o padrao contido na linha.
Voltando ao exemplo, qual e' o pedaco da linha que casa com o
padrao? Bom, esse e' um outro problema sutil com as regex'es, que aparece
com alguma frequencia quando se usa o metacaracter "*". Essa regex casa
com a cadeia nula em varios lugares (alias, a cadeia inteira tambem casa
com a cadeia nula), e a cadeia nula sempre faz parte de qualquer cadeia.
A cadeia "<NULA>uv" casa com essa regex:
([^aeiou]*a)*([^aeiou]*e)*([^aeiou]*i)*([^aeiou]*o)*([^aeiou]*u)*[^aeiou]*
^^^ NULA ^^^ ^^^ NULA ^^^ ^^^ NULA ^^^ ^^^ NULA ^^^ ^^NULA^^ u v
e, por isso, o grep retorna a linha inteira (uva). Mas qualquer linha vai
casar com essa regex porque, no "pior caso", a regex inteira casa com a
cadeia nula.
Ou seja, a regex dada casa realmente apenas com as cadeias que contem as
vogais em ordem, mas nao e' uma regex muito util para ser usada com o
grep; mas ela e' util para ser usada em outros lugares. Por exemplo, se
quisermos extrair os pedacos das linhas que casam com essa regex, podemos
usar o seguinte script awk:
match ($0,
/([^aeiou]*a)*([^aeiou]*e)*([^aeiou]*i)*([^aeiou]*o)*([^aeiou]*u)*[^aeiou]*/);
print substr ($0, RSTART, RLENGTH);
Se o que queremos e' achar linhas inteiras que formam uma cadeia onde as
vogais estao em ordem, podemos usar o grep e explicitar o inicio e o fim
da linha:
^([^aeiou]*a)*([^aeiou]*e)*([^aeiou]*i)*([^aeiou]*o)*([^aeiou]*u)*[^aeiou]*$
Com isso, linhas vazias sao aceitas tambem, mas qualquer linha com vogais
tem que ter as vogais em ordem.
E' isso ai'.
Ate' +
Nelson