:TITLE: Expressões Regulares 101
;#
;# RCSID: $Header: /home/cvs/TclTutor3/lesson/Tcl_Portuguese/Tcl_Portuguese20.lsn,v 1.1 2008/08/02 12:37:36 clif Exp $
;# Copyright (c) 1995 Clif Flynt
;# 9300 Fleming Rd.
;# Dexter, MI  48130
;# clif@cflynt.com
;# Veja o arquivo "AVISO" com os termos da licença.
;#
;#*********************************************************
;# Portuguese translation: Lucio Agostinho Rocha
;# E-mail: outrosdiasvirao@yahoo.com.br
;# Last update: 04/01/2006
;#*********************************************************
:LESSON_TEXT_START_LEVEL 0:
Tcl também suporta operações de string que usam o pacote de expressões
regulares escrito por Henry Spencer. Muitos comandos podem acessar esses
métodos com um argumento -regexp. Veja as páginas do manual para saber
quais comandos suportam expressões regulares.
<P>
Há também dois comandos explícitos para tratar expressões regulares.
<DL>
<B><DT>regexp</B> <I>?modificadores? exp string ?varBusca? ?varSubBusca1... varSubBuscaN?</I>
<DD>Pesquisa na <I>string</I> pela expressão regular <I>exp</I>.  Se um
parâmetro <I>varBusca</I> é fornecido, então a substring que é compatível com a
expressão regular é copiada para <I>varBusca</I>. Se
as variáveis <I>varSubBuscaN</I> existem, então as partes entre parênteses
da pesquisa na string são copiadas para as variáveis <I>varSubBusca</I>, 
trabalhando da esquerda para a direitra.
<B><DT>regsub</B> <I>?modificadores? exp string varSubstituição nomeVar</I>
<DD>Pesquisa na <I>string</I> por substrings que sejam compatíveis com
a expressão <I>exp</I> e as substitui com <I>varSubstituição</I>. A string
resultante é copiada para <I>nomeVar</I>.
</DL>
<P>
Expressões regulares podem ser expressas em apenas algumas poucas regras.
<DL>
<DT>^
<DD>Encontra o início de uma string
<DT>$
<DD>Encontra o fim de uma string
<DT>.
<DD>Encontra qualquer caracter
<DT>*
<DD>Encontra qualquer quantidade (0-n) do caracter anterior
<DT>+
<DD>Encontra qualquer quantidade, mas ao menos 1 quantidade do caracter anterior
<DT>[...]
<DD>Encontra qualquer caracter de um conjunto de caracteres
<DT>[^...]
<DD>Encontra qualquer caracter que *NÃO* é membro do conjunto de
caracteres seguido pelo ^.
<DT>(...)
<DD>Delimita um conjunto de caracteres que poderão ser
atribuídos às <I>varBusca</I> e <I>varSubBusca</I>
</DL>
<P>
Expressões regulares são similares ao <I>globbing</i> que foi discutido
nas lições 15 e 17. A principal diferença está na forma que conjuntos
de pesquisa de caracteres são manipulados. No <I>globbing</I> a única forma
de selecionar um conjunto de texto desconhecido é com o símbolo 
<B>*</B>. Isso permite uma pesquisa na string por qualquer quantidade de
qualquer caracter.
<P>
No tratamento da expressão regular, o símbolo <B>*</B> busca zero ou mais
ocorrências do caracter imediatamente seguinte ao <B>*</B>.  Por exemplo,
<B>a*</B> encontraria a, aaaaa, ou uma string vazia. Se o caracter diretamente
antes do <B>*</B> for um conjunto de caracteres delimitados por colchetes, 
então o <B>*</B> irá encontrar qualquer quantidade de todos esses caracteres.
Por exemplo, <B>[a-c]*</B> encontraria aa, abc, aabcabc, ou novamente,
uma string vazia.
<P>
O símbolo <B>+</B> se comporta quase da mesma forma que o <B>*</B>, exceto que
retorna ao menos um caracter na pesquisa. Por exemplo, <B>[a-c]+</B>
encontraria aa, abc, ou aabcabc, mas não uma string vazia.
<P>
O comando <B>regexp</B> é similar ao comando <B>string match</B> na forma
que ele busca uma <B>exp</B> em uma string. A diferença é que <B>regexp</B>
pode fazer buscas em uma porção de uma string, ao invés de em toda ela, e
colocar os caracteres encontrados na variável <B>varBusca</B>.
<P>
Se uma busca é encontrada para uma porção de uma expressão regular
delimitada por parênteses, <B>regexp</B> irá copiar o subconjunto de
caracteres encontrados para o argumento <B>varSubBusca</B>. Isso
pode ser usado para tratar strings simples.
<P>
<B>Regsub</B> irá copiar o conteúdo da string para uma nova variável
substituindo os caracteres compatíveis com <B>exp</B> pelos caracteres na
<B>varSubstituição</B>. Se <I>varSubstituição</I> contém um <B>&</B> ou <B>\0</B>, 
então aqueles caracteres serão subsituídos pelos caracteres que são
compatíveis com <I>exp</I>. Se o número seguinte à barra invetida for um
número de 1 a 9, então aquela seqüência de barra invertida será
substituida pela porção apropriada de <I>exp</I> que estiver delimitada
por parênteses.

:TEXT_END:

:LESSON_TEXT_START_LEVEL 1:
Tcl também suporta operações de string que usam o pacote de expressões
regulares escrito por Henry Spencer. Muitos comandos podem acessar esses
métodos com um argumento -regexp. Veja as páginas do manual para saber
quais comandos suportam expressões regulares.
<P>
Há também dois comandos explícitos para tratar expressões regulares.
<DL>
<B><DT>regexp</B> <I>?modificadores? exp string ?varBusca? ?varSubBusca1... varSubBuscaN?</I>
<DD>Pesquisa na <I>string</I> pela expressão regular <I>exp</I>.  Se um
parâmetro <I>varBusca</I> é fornecido, então a substring que é compatível com a
expressão regular é copiada para <I>varBusca</I>. Se
as variáveis <I>varSubBuscaN</I> existem, então as partes entre parênteses
da pesquisa na string são copiadas para as variáveis <I>varSubBusca</I>, 
trabalhando da esquerda para a direitra.
<B><DT>regsub</B> <I>?modificadores? exp string varSubstituição nomeVar</I>
<DD>Pesquisa na <I>string</I> por substrings que sejam compatíveis com
a expressão <I>exp</I> e as substitui com <I>varSubstituição</I>. A string
resultante é copiada para <I>nomeVar</I>.
</DL>
<P>
Expressões regulares podem ser expressas em apenas algumas poucas regras.
<DL>
<DT>^
<DD>Encontra o início de uma string
<DT>$
<DD>Encontra o fim de uma string
<DT>.
<DD>Encontra qualquer caracter
<DT>*
<DD>Encontra qualquer quantidade (0-n) do caracter anterior
<DT>+
<DD>Encontra qualquer quantidade, mas ao menos 1 quantidade do caracter anterior
<DT>[...]
<DD>Encontra qualquer caracter de um conjunto de caracteres
<DT>[^...]
<DD>Encontra qualquer caracter que *NÃO* é membro do conjunto de
caracteres seguido pelo ^.
<DT>(...)
<DD>Delimita um conjunto de caracteres que poderão ser
atribuídos às <I>varBusca</I> e <I>varSubBusca</I>
</DL>
<P>
Expressões regulares são similares ao <I>globbing</i> que foi discutido
nas lições 15 e 17. A principal diferença está na forma que conjuntos
de pesquisa de caracteres são manipulados. No <I>globbing</I> a única forma
de selecionar um conjunto de texto desconhecido é com o símbolo 
<B>*</B>. Isso permite uma pesquisa na string por qualquer quantidade de
qualquer caracter.
<P>
No tratamento da expressão regular, o símbolo <B>*</B> busca zero ou mais
ocorrências do caracter imediatamente seguinte ao <B>*</B>.  Por exemplo,
<B>a*</B> encontraria a, aaaaa, ou uma string vazia. Se o caracter diretamente
antes do <B>*</B> for um conjunto de caracteres delimitados por colchetes, 
então o <B>*</B> irá encontrar qualquer quantidade de todos esses caracteres.
Por exemplo, <B>[a-c]*</B> encontraria aa, abc, aabcabc, ou novamente,
uma string vazia.
<P>
O símbolo <B>+</B> se comporta quase da mesma forma que o <B>*</B>, exceto que
retorna ao menos um caracter na pesquisa. Por exemplo, <B>[a-c]+</B>
encontraria aa, abc, ou aabcabc, mas não uma string vazia.
<P>
O tratamento de expressões regulares tem uma maneira mais poderosa
de tratar colchetes que o <I>globbing</I>. Com <I>globbing</I> você
pode usar colchetes para delimitar um conjunto de caracteres onde qualquer
um poderá ser encontrado. O tratamento de expressões regulares também
inclui um método de selecionar qualquer caracter que não está em um
conjunto. Se o primeiro caracter depois do <B>[</B> for um <B>^</B>, então
o tratador da expressão regular irá encontrar qualquer caracter que
não está no conjunto de caracteres entre os colchetes. Um <B>^</B> pode
ser incluido no conjunto de caracteres a serem encontrados (ou não)
colocando-o em qualquer outra posição.
<P>
O comando <B>regexp</B> é similar ao comando <B>string match</B> na forma
que ele busca uma <B>exp</B> em uma string. A diferença é que <B>regexp</B>
pode fazer buscas em uma porção de uma string, ao invés de em toda ela, e
colocar os caracteres encontrados na variável <B>varBusca</B>.
<P>
Se uma busca é encontrada para uma porção de uma expressão regular
delimitada por parênteses, <B>regexp</B> irá copiar o subconjunto de
caracteres encontrados para o argumento <B>varSubBusca</B>. Isso
pode ser usado para tratar strings simples.
<P>
<B>Regsub</B> irá copiar o conteúdo da string para uma nova variável
substituindo os caracteres compatíveis com <B>exp</B> pelos caracteres na
<B>varSubstituição</B>. Se <I>varSubstituição</I> contém um <B>&</B> ou <B>\0</B>, 
então aqueles caracteres serão substituídos pelos caracteres que são
compatíveis com <I>exp</I>. Se o número seguinte à barra invetida for um
número de 1 a 9, então aquela seqüência de barra invertida será
substituida pela porção apropriada de <I>exp</I> que estiver delimitada
por parênteses.
<P>
Note que o argumento <B>exp</B> para <CODE>regexp </CODE> ou <CODE>regsub</CODE> é
processado pelo passo de substituição Tcl, e esteja certo de colocar a barra
invertida antes de caracteres significativos.
:TEXT_END:

:LESSON_TEXT_START_LEVEL 2:
Tcl também suporta operações de string que usam o pacote de expressões
regulares escrito por Henry Spencer. Muitos comandos podem acessar esses
métodos com um argumento -regexp. Veja as páginas do manual para saber
quais comandos suportam expressões regulares.
<P>
Há também dois comandos explícitos para tratar expressões regulares.
<DL>
<B><DT>regexp</B> <I>?modificadores? exp string ?varBusca? ?varSubBusca1... varSubBuscaN?</I>
<DD>Pesquisa na <I>string</I> pela expressão regular <I>exp</I>.  Se um
parâmetro <I>varBusca</I> é fornecido, então a substring que é compatível com a
expressão regular é copiada para <I>varBusca</I>. Se
as variáveis <I>varSubBuscaN</I> existem, então as partes entre parênteses
da pesquisa na string são copiadas para as variáveis <I>varSubBusca</I>, 
trabalhando da esquerda para a direitra.
<B><DT>regsub</B> <I>?modificadores? exp string varSubstituição nomeVar</I>
<DD>Pesquisa na <I>string</I> por substrings que sejam compatíveis com
a expressão <I>exp</I> e as substitui com <I>varSubstituição</I>. A string
resultante é copiada para <I>nomeVar</I>.
</DL>
<P>
Expressões regulares podem ser expressas em apenas algumas poucas regras.
<DL>
<DT>^
<DD>Encontra o início de uma string
<DT>$
<DD>Encontra o fim de uma string
<DT>.
<DD>Encontra qualquer caracter
<DT>*
<DD>Encontra qualquer quantidade (0-n) do caracter anterior
<DT>+
<DD>Encontra qualquer quantidade, mas ao menos 1 quantidade do caracter anterior
<DT>[...]
<DD>Encontra qualquer caracter de um conjunto de caracteres
<DT>[^...]
<DD>Encontra qualquer caracter que *NÃO* é membro do conjunto de
caracteres seguido pelo ^.
<DT>(...)
<DD>Delimita um conjunto de caracteres que poderão ser
atribuídos às <I>varBusca</I> e <I>varSubBusca</I>
</DL>
<P>
Expressões regulares são similares ao <I>globbing</i> que foi discutido
nas lições 15 e 17. A principal diferença está na forma que conjuntos
de pesquisa de caracteres são manipulados. No <I>globbing</I> a única forma
de selecionar um conjunto de texto desconhecido é com o símbolo 
<B>*</B>. Isso permite uma pesquisa na string por qualquer quantidade de
qualquer caracter.
<P>
No tratamento da expressão regular, o símbolo <B>*</B> busca zero ou mais
ocorrências do caracter imediatamente seguinte ao <B>*</B>.  Por exemplo,
<B>a*</B> encontraria a, aaaaa, ou uma string vazia. Se o caracter diretamente
antes do <B>*</B> for um conjunto de caracteres delimitados por colchetes, 
então o <B>*</B> irá encontrar qualquer quantidade de todos esses caracteres.
Por exemplo, <B>[a-c]*</B> encontraria aa, abc, aabcabc, ou novamente,
uma string vazia.
<P>
O símbolo <B>+</B> se comporta quase da mesma forma que o <B>*</B>, exceto que
retorna ao menos um caracter na pesquisa. Por exemplo, <B>[a-c]+</B>
encontraria aa, abc, ou aabcabc, mas não uma string vazia.
<P>
O tratamento de expressões regulares tem uma maneira mais poderosa
de tratar colchetes que o <I>globbing</I>. Com <I>globbing</I> você
pode usar colchetes para delimitar um conjunto de caracteres onde qualquer
um poderá ser encontrado. O tratamento de expressões regulares também
inclui um método de selecionar qualquer caracter que não está em um
conjunto. Se o primeiro caracter depois do <B>[</B> for um <B>^</B>, então
o tratador da expressão regular irá encontrar qualquer caracter que
não está no conjunto de caracteres entre os colchetes. Um <B>^</B> pode
ser incluido no conjunto de caracteres a serem encontrados (ou não)
colocando-o em qualquer outra posição.
<P>
O comando <B>regexp</B> é similar ao comando <B>string match</B> na forma
que ele busca uma <B>exp</B> em uma string. A diferença é que <B>regexp</B>
pode fazer buscas em uma porção de uma string, ao invés de em toda ela, e
colocar os caracteres encontrados na variável <B>varBusca</B>.
<P>
Se uma busca é encontrada para uma porção de uma expressão regular
delimitada por parênteses, <B>regexp</B> irá copiar o subconjunto de
caracteres encontrados para o argumento <B>varSubBusca</B>. Isso
pode ser usado para tratar strings simples.
<P>
<B>Regsub</B> irá copiar o conteúdo da string para uma nova variável
substituindo os caracteres compatíveis com <B>exp</B> pelos caracteres na
<B>varSubstituição</B>. Se <I>varSubstituição</I> contém um <B>&</B> ou <B>\0</B>, 
então aqueles caracteres serão substituídos pelos caracteres que são
compatíveis com <I>exp</I>. Se o número seguinte à barra invetida for um
número de 1 a 9, então aquela seqüência de barra invertida será
substituida pela porção apropriada de <I>exp</I> que estiver delimitada
por parênteses.
<P>
Se você não clicou no botão <B>Executar exemplo</B> ainda, faça isso
agora, e observe a saída enquanto você lê o restante dessa lição.
<P>
O argumento <B>exp</B> para <CODE>regexp </CODE> ou <CODE>regsub</CODE> é
processado pelo passo de substituição Tcl. Isso afeta o mecanismo de como
expressões regulares podem ser formadas. Se a expresão regular não tem
seqüências de barra invertida que você deseja ter convertidas pelo passo
de substituição Tcl, então o argumento <B>exp</B> pode ser delimitado por
chaves. Se você quiser que substituições ocorram, o argumento <B>exp</B> 
deve ser delimitado por aspas duplas. Neste caso, caracteres que têm
significado na fase de substituição Tcl devem ser precedidos com uma
barra invertida.
<P>
Nestes exemplos, não há seqüência de barra invertida, então ou chaves ou
aspas duplas poderiam ser usada para agrupar a string <I>exp</I>. Nos primeiros
dois exemplos, o colchete é usado para definir um intervalo de caracteres
aceitáveis, então é mais simples usar colchetes nesses casos.
<P>
O primeiro exemplo simplesmente encontra o primeiro conjunto de caracteres
minúsculos. Ele não irá encontrar um caracter maiúsculo, e não irá encontrar
um espaço. Então, é encontrado "nde", as primeiras três letras minúsculas,
rodeadas de um lado pela letra maíúscula "O", e de outro pelo espaço.
<P>
O segundo exemplo mostra as primeiras 2 palavras da frase sendo
tratadas em variáveis separadas. A seqüência <CODE>([A-Za-z]+)</CODE> seleciona
qualquer número (mas ao menos um) de letras maiúsculas ou minúsculas. Os
parênteses ao redor dessa seqüência fazem com que os caracteres que forem
encontrados nessa expressão regular sejam copiados para a primeira variável
<I>varSubBusca1</I>. Neste caso, as letras "Onde" são copiadas para
<CODE>varSubBusca1</CODE>.
<P>
A próxima seqüência é o "<CODE> +</CODE>". Ela busca qualquer número de
espaços, mas ao menos um espaço deverá ser encontrado.
<P>
A última seqüência na <I>exp</I> é <CODE>([a-z]+)</CODE>, que busca
qualquer quantidade (mas ao menos uma) de letras minúsculas, e as copia
na segunda variável <I>varSubBusca2</I>.
<P>
O último exemplo mostra uma expressão regular simples com
<CODE>"caminho"</CODE> sendo substituído pela string "estrada" 
na frase do exemplo.
<P>
Tente mudar o <CODE>"caminho"</CODE> para uma expressão regular generalizada e
veja o que acontece.

:TEXT_END:

:CODE_START:
set exemplo "Onde houver esperança, haverá um caminho."

set resultado [regexp {[a-z]+} $exemplo varBusca]
puts "Resultado: $resultado encontrado: $varBusca"

set result [regexp {([A-Za-z]+) +([a-z]+)} $exemplo varBusca varSubBusca1 varSubBusca2 ]
puts "Resultado: $resultado encontrado: $varBusca 1: $varSubBusca1 2: $varSubBusca2"

regsub "esperança" $exemplo "estrada" exemplo2
puts "Nova string: $exemplo2"

:TEXT_END:

