Express�es Regulares
Abstrato::
express�es regulares que s�o usadas para contexto avan�ado em procuras sens�veis e modifica��es de texto. Eles podem ser achados em muitos editores avan�ados, e em programas de editora��o eletronica e em idiomas.
Introdu��o
As Express�es Regulares podem ser encontradas em muitos editores como vi, emacs, e em programas como grep, egrep e em linguagens de programa��o como awk, perl e sed.
As Express�es Regulares s�o usadas para buscas avan�adas dependendo do contexto. Por isso podemos dizer que as Express�es Regulares n�o s�o apenas um localizador de cadeias de texto,
sim que s�o a descri��o formal de um protetor do texto.
Quando v� pela primeira vez como poder�amos editar textos com a ajuda das Express�es Regulares, fiquei fascinado. Modifica��es em um texto, para os que os tivesse utilizado durante horas, ficavam prontas em poucos segundos. O que com certeza se veria no monitor, parecia um conjunto de pontos, h�fens e outros s�mbolos. Com certeza alguma coisa estava claro: Queria aprender a linguagem das Express�es Regulares e o que me deixou impressionado, era a facilidade para entender. Segue abaixo, algumas regras de sintaxe muito simples.
Apesar de que as Express�es Regulares estejem muito extendidas no mundo Unix, n�o existe uma linguagem standard de Express�es Regulares. Mas se bem que poderemos falar de diferentes dialetos. Existem por exemplo dois representantes do conhecido programa grep, egrep e grep. Ambos usam as Express�es Regulares com capacidades ligeiramente diferentes. Perl pode ser qualificada como a linguagem com a sintaxe de Express�es Regulares mais desenvolvida. Com sorte todos estes dialetos seguem os mesmos princ�pios e no momento em que os entendemos, o resto ser� f�cil.
Neste artigo me dedicarei exclusivamente aos pr�ncipios b�sicos, os detalhes que poderemos consultar nas p�ginas dos manuais (man-pages).
Um pequeno exemplo
Suponhamos que tenhamos a seguinte lista de telefones de uma empresa:
Fone Nome ID
...
...
3412 Bob 123
3834 Jonny 333
1248 Kate 634
1423 Tony 567
2567 Peter 435
3567 Alice 535
1548 Kerry 534
...
Estamos tratando com uma empresa com 500 pessoas e os dados est�o armazenados em um arquivo ASCII normal. Os registros de pessoas cujo telefone comece com 1, trabalham no edif�cio 1. Quem trabalha no Edif�cio 1?
Uma Express�o Regular poder� responder a esta quest�o:
grep '^1' phonelist.txt
ou
egrep '^1' phonelist.txt
ou
perl -ne 'print if (/^1/)' phonelist.txt
Em palavras normais isto significa: Procura todas as linhas que comecem com um 1. O s�mbolo "^" � o encarregado de indicar que s�mente encontrem os n�meros 1 que se encontrem no pr�ncipio da linha.
Regras de sintaxe
Padr�o s� com um s�mbolo
O elemento b�sico de uma express�o regular � o padr�o de s� um s�mbolo. Este padr�o
s�mente � efetivado quando este s�mbolo puder ser encontrado exatamente como o texto.
Um exemplo do que podemos encontrar com o n�mero 1 do exemplo acima.
Outro exemplo para o padr�o de s� um s�mbolo
�:
egrep 'Kerry' phonelist.txt
Este padr�o se comp�e de padr�es de s� um s�mbolo (a letra K, e, etc.)
V�rios signos podem ser agrupados em um conjunto. Um conjunto � representado com um par de colchetes (o de abrir e o de fechar) e uma lista de caracteres entre eles. Um conjunto tamb�m
� considerado como um padr�o de s� um s�mbolo. A busca deste conjunto se efetivar� quando encontramos um e s� um dos signos do conjunto do texto. Um exemplo:
[abc] Um padr�o de um s� s�mbolo com o
qual poderemos encontrar o s�mbolo a, b ou c.
[ab0-9] Um padr�o de s� um s�mbolo no qual
se procura um a ou um b ou um n�mero
que se encontre entre o 0 e o 9 no c�digo ASCII.
[a-zA-Z0-9\-] Este procura uma letra mai�scula ou min�scula
ou um n�mero ou o signo -.
Numa lista de telefone:
egrep '^1[348]' phonelist.txt
Esta express�o procura linhas que comecem com 13, 14 ou 18.
A maioria dos s�mbolos ASCII nos leva a uma busca hesitante quando se procura no texto, mas tamb�m encontramos s�mbolos em uma express�o regular que tem um significado especial. Os colchetes at� a direita indicam o come�o da defini��o de um conjunto. O s�mbolo "-" em um conjunto � um s�mbolo especial e representa uma categoria especial no sistema de s�mbolos
ASCII. Para indicar que nos referimos ao significado normal do s�mbolo, se coloca uma barra invertida antes "\". Por exemplo, na express�o [a-zA-Z0-9\-]. Em alguns dialetos encontramos que a barra invertida junto a outro s�mbolo tem um significado especial. Neste caso se obtem o significado normal retirando a barra invertida.
O ponto tamb�m � um s�mbolo importante em uma express�o regular. A busca ser� efetiva
quando o s�mbolo comparado seja qualquer s�mbolo menos o s�mbolo de nova linha do c�digo
ASCII.
Exemplo:
grep '^.2' phonelist.txt
Esta express�o procura linhas que contenham o n�mero 2 na segunda posi��o e qualquer outro s�mbolo antes.
Os pontos podem ser invertidos mediante a coloca��o de "[^" en lugar de "[" na express�o. Neste caso o s�mbolo "^" n�o representa o come�o da linha, sim que "[" e "^" juntos representam o inverso do conjunto.
[0-9] Um padr�o de s� um s�mbolo, a procura
ser� efetivada se o s�mbolo no texto � um n�mero.
[^0-9] Tudo o que seja um n�mero.
[^abc] Tudo o que seja um a, b ou c.
. Tudo menos o s�mbolo de linha nova. � identico a
[^\n]. \n � o s�mbolo para uma nova linha.
Para procurar todas as l�nhas que N�O comecem com um 1, escrever�amos:
egrep '^[^1]' phonelist.txt
�ncoras (anchors)
Antes vimos que "^" representava o in�cio de uma linha. As �ncoras s�o s�mbolos especiais
nas express�es regulares que n�o demonstram um s�mbolo e sim uma posi��o.el inicio de una
^ Inicio de uma linha
$ Final de uma linha
Para encontrar pessoas em nossa lista com um indicativo company-ID) de 567, utilizaremos a express�o:
egrep '567$' phonelist.txt
Significa: Procure linhas que finalizem com 567.
Multiplicadores
Os multiplicadores nos indicam, quantas vezes tem de aparecer um padr�o de s�
um s�mbolo no texto:
Descri��o | grep | egrep | perl | vi | vim | vile
| elvis | emacs |
zero ou mais vezes | * | * | * | * | * | * | * | * |
uma ou mais vez | \{1,\} | + | + | | \+ | \+ | \+ | + |
zero o uma vez | \? | ? | ? | | \= | \? | \= | ? |
de n at� m vezes | \{n,m\} | | {n,m} | | | | \{n,m\} | \{n,m\} |
Nota: Para os distintos VI teria que utilizar a op��o magic.
Um exemplo da lista de telefones:
....
1248 Kate 634
....
1548 Kerry 534
....
Para encontrar uma p�gina que se componha de um 1, v�rios n�meros, v�rios espa�os e a letra K, escrever�amos:
grep '^1[0-9]\{1,\} \{1,\}K' phonelist.txt
ou utilizar�amos * e repetimos [0-9] e o espa�o:
grep '^1[0-9][0-9]* *K' phonelist.txt
ou
egrep '^1[0-9]+ +K' phonelist.txt
ou
perl -ne 'print if (/^1[0-9]+ +K/)' phonelist.txt
Os multiplicadores nos indicam, quantas vezes tem que aparecer o padr�o de s� um
s�mbolo que os precede. "23*4" N�O significa "2, 3, talv�z alguma coisa e depois
um 4" (isto seria "23.*4"), sen�o que significa, que se est� buscando "un 2, talv�z
alguns 3 e um 4".
� importante saber que um multiplicador � �vido. Isto significa que o primeiro multiplicador se extender� ao m�ximo que possa at� a direita.
Isto n�o � muito importante no grep, mas, � importante no momento de editar textos.
A express�o ^1.*4
se extenderia por toda linha
1548 Kerry 534
do in�cio at� o fim.
A express�o n�o se extende s�mente at� a zona curta, o seja, 154, sen�o at� o m�ximo
que possa.
Parenteses como memoria
Os parentesis como mem�ria n�o influem no tipo ou s�mbolos que se busca. Servem para que
os fragmentos do texto se armazenem e possamos encontr�-los atrav�s de vari�veis.
O primeiro parentese ser� referenciado como vari�vel 1, o segundo como vari�vel 2, etc.
Nome do programa | Sintaxe do parentese | Sintaxe das vari�veis |
grep | \(\) | \1 |
egrep | () | \1 |
perl | () | \1 or ${1} |
vi,vim,vile,elvis | \(\) | \1 |
emacs | \(\) | \1 |
Um exemplo:
A express�o [a-z] [a-z]
procura duas letras min�sculas.
Agora podemos utilizar estas vari�veis, para procurar padr�es de texto como ?otto?:
egrep '([a-z])([a-z])\2\1'
A vari�vel \1 comt�m a letra o
e \2 a letra t.
A express�o serviria tamb�m para anna, mas n�o para yxyx.
Os parenteses n�o s�o utilizados normalmente para procura de nomes como otto e anna,
sen�o para editar ou para procurar e substituir.
Uso das Express�es Regulares para o tratamento de Textos
Para editar textos � necess�rio um editor de textos como vi ou emacs ou perl.
Todos estes programas suportam express�es regulares.
No emacs utilizamos M-x query-replace-regexp ou replace-regexp. M-x query-replace-regexp
pede confirma��o em cada procura e substitui��o. O mais recomend�vel � atribuir uma tecla de fun��o ao query-replace ou replace-regexp.
No vi utilizamos :%s/ / /gc. O s�mbolo % representa a Ex-regi�o ?todo o arquivo? no que podemos recome�ar por qualquer outra Ex-region. No editor vim, por exemplo, podemos marcar uma regi�o com mai�scula-v e o cursor acima/abaixo. Desgra�adamente o artigo sairia de seus
prop�sitos sem que n�o d�ssemos uma pequena introdu��o sobre vim. ///gc � interativo e
pede por uma confirma��o. s///g n�o � interativo. No perl utilizamos:
perl -pe 's/ / /g'
Agora alguns exemplos. Na empresa temos que modificar alguns telefones. Todos os telefones
que come�am com um 1, tem que ter um 2 depois do segundo n�mero. De 1423 passaremos para
14223.
Fone Nome ID
...
3412 Bob 123
3834 Jonny 333
1248 Kate 634
1423 Tony 567
2567 Peter 435
3567 Alice 535
1548 Kerry 534
...
e isto � assim de f�cil:
vi: s/^\(1.\)/\12/g
emacs: ^\(1.\) sustituir por \12
perl: perl -pe 's/^(1.)/${1}2/g' phonelist.txt
A lista de telefones aparecer� assim:
Fone Nome ID
...
3412 Bob 123
3834 Jonny 333
12248 Kate 634
14223 Tony 567
2567 Peter 435
3567 Alice 535
15248 Kerry 534
...
Perl n�o s�mente conhece as vari�veis \1 \9. \12 apontaria para a
vari�vel 12. Para solucionar o problema utilizamos simplesmente ${1}.
Mas agora n�o encontramos as colunas bem alinhadas.
Como poder�amos solucionar
isto? Poder�amos comprovar se h� um espa�o na quinta
posi��o e inserir outro.
vi: s/^\(....\) /\1 /g
emacs: '^\(....\) ' sustituir por '\1 '
perl: perl -pe 's/^(....) /${1} /g' phonelist.txt
Agora temos:
Fone Nome ID
...
3412 Bob 123
3834 Jonny 333
12248 Kate 634
14223 Tony 567
2567 Peter 435
3567 Alice 535
15248 Karry 534
...
Um colega editou a phonelist.txt e n�o teve o devido cuidado.
No princ�pio de alguma linha encontramos espa�os. Como poderemos solucionar?
Fone Nome ID
...
3412 Bob 123
3834 Jonny 333
12248 Kate 634
14223 Tony 567
2567 Peter 435
3567 Alice 535
15248 Kerry 534
...
Isto ter� que solucionar o problema:
vi: s/^ *// (existem dois espa�os, j� que n�o temos o +)
emacs: '^ +' substituir pela cadeia vazia
perl: perl -pe 's/^ +//' phonelist.txt
Estás escrevendo um programa e utiliza as vari�veis
temp y temporary. Agora queres substituir a variavel temp pela vari�vel
counter. Se utilizasse a op��o de procurar e substituir,verias
que a vari�vel temporary seria substituida por counterorary. Isto
queres evitar.
Com as express�es regularesfaremos bem f�cil. Se
substituirmos temp([^o]) com counter\1. Com isto, substituiremos temp e n�o "o".
(Outra alternativa seriam as Boundaries, que n�o foi comentada aqui.)
Espero que este artigo tenha despertado sua curiosidade. Se desejas continuar, sugiro consultar as man-pages de teu editor preferido.
Existem mais s�mbolos especiais nas express�es regulares, como por exemplo,
Alterations, Art Order, e naturalmente as Boundaries.
Que disfrutes ent�o
|