[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...)



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