Escolar Documentos
Profissional Documentos
Cultura Documentos
Apostila Conhecendo Regex
Apostila Conhecendo Regex
Abril de 2004
ndice
Sobre o Curso...........................................................................................................1
Introduo..................................................................................................................2
O ambiente de testes................................................................................................3
Conhecendo o arquivo /etc/passwd..................................................................3
Conhecendo o comando grep...........................................................................4
Conhecendo cada um dos metacaracteres............................................................5
O circunflexo ^...................................................................................................5
O cifro $...........................................................................................................5
A lista [].............................................................................................................6
O ponto ............................................................................................................7
As chaves {}......................................................................................................8
O curinga .* (AND)............................................................................................9
O ou | (OR)......................................................................................................10
Os outros repetidores: ? * +............................................................................10
A lista negada [^].............................................................................................10
O intervalo em listas []...................................................................................11
A tabela ASCII..........................................................................................................12
A tabela dos metacaracteres.................................................................................13
Escapar ou no escapar?.......................................................................................14
Para saber mais.......................................................................................................15
Sobre o Curso
Nome
Conhecendo as Expresses Regulares
Instrutor
Aurlio Marinho Jargas (http://aurelio.net)
Objetivo
Desmistificar e ensinar aos alunos todos os metacaracteres bsicos,
preparandoos para comporem suas prprias expresses.
PrRequisitos
Noes bsicas de informtica e operao do sistema pela linha de comando.
Pblico Alvo
Desenvolvedores, administradores de sistemas, programadores e
interessados em geral.
Durao
8 horas
Introduo
Expresses Regulares. Um assunto que muitos torcem o nariz ao ouvir falar, mas
que sempre acaba aparecendo na resoluo dos mais diversos problemas.
Para quem no conhece ou no domina o assunto, difcil perceber a utilidade de
saber escrever todos aqueles smbolos estranhos. Mas medida que vai se
aprendendo, aplicando, tudo comea a clarear.
Este minicurso apresentar os componentes utilizados nas expresses e ensinar
como utilizlos.
Uma Expresso Regular (ER) um mtodo formal de se especificar um padro de
texto.
uma composio de smbolos, caracteres com funes especiais, chamados
"metacaracteres" que, agrupados entre si e com caracteres literais, formam uma
seqncia, uma expresso. Essa expresso testada em textos e retorna sucesso
caso esse texto obedea exatamente a todas as suas condies. Dizse que o
texto "casou" com a expresso.
A ERs servem para se dizer algo abrangente de forma especfica. Definido o padro
de busca, temse uma lista (finita ou no) de possibilidades de casamento. Em um
exemplo rpido, [rgp]ato pode casar "rato", "gato" e "pato".
As ERs so teis para buscar ou validar textos variveis como:
data
horrio
nmero IP
endereo de email
endereo de Internet
declarao de uma funo()
dados na coluna N de um texto
dados que esto entre <tags></tags>
nmero de telefone, RG, CPF, carto de crdito
Vrios editores de texto e linguagens de programao tm suporte a ERs, ento o
tempo investido em seu aprendizado recompensado pela larga variedade de
aplicativos onde ele pode ser praticado.
O ambiente de testes
Para conhecer e desvendar os segredos das Expresses Regulares, usaremos o
comando grep, que serve para "pescar" linhas dentro de um texto. Voc informa
uma palavra e o grep retorna todas as linhas do texto em que ele encontrar essa
palavra.
Todas as senhas esto protegidas em outro arquivo, por isso h somente uma letra
"x" em seu lugar. Analisando a primeira linha, sabemos que ela referente ao
administrador do sistema ("root"). Seu nmero de usurio (UID) e seu nmero de
grupo so iguais: zero. Seu nome "root" mesmo, seu diretrio padro o "/root" e
seu shell de login "bash".
Epa! Alm da linha do root, o grep retornou tambm a linha do usurio "operator".
Mas por que isso se a pesquisa era somente por "root"?
Olhando mais atentamente para a linha do usurio operator, vemos que o seu
diretrio $HOME "/root". Como dissemos ao grep "procure por root", as duas
linhas so resultados vlidos.
Para obter somente a linha desejada, seria preciso haver uma maneira de dizer ao
grep "procure por root no incio da linha". neste momento que as Expresses
Regulares entram em cena.
Alm de palavras, o grep tambm entende ERs. Uma expresso formada por
caracteres normais que formam palavras (letras e nmeros) como "root", mas
tambm por smbolos especais, os chamados metacaracteres.
O circunflexo ^
O primeiro metacaractere que veremos o circunflexo "^" (ou chapuzinho), que
simboliza o incio de uma linha. Podemos uslo para resolver o problema anterior
de obter somente a linha do usurio root:
$ grep ^root /etc/passwd
root:x:0:0:root:/root:/bin/bash
$
O cifro $
O circunflexo chamado de metacaractere de posicionamento, pois representa uma
posio especfica da linha. Seu primo o cifro "$", que representa o fim de uma
linha.
Lembra que o ltimo campo de cada linha do arquivo "passwd" o shell de login do
usurio? Agora com o metacaractere cifro podemos pesquisar todos os usurios,
alm do root, que usam o "bash" como shell:
$ grep bash$ /etc/passwd
root:x:0:0:root:/root:/bin/bash
mysql:x:27:27:MySQL Server:/var/lib/mysql:/bin/bash
carlos:x:500:500:carlos:/home/carlos:/bin/bash
ana:x:501:501:Ana Paula Moreira:/home/ana:/bin/bash
acs:x:502:502:Antonio Carlos Silva:/home/acs:/bin/bash
$
A lista []
Mudando um pouco de tarefa, que tal pesquisar os usurios que possuem o nome
"Carlos"? No arquivo de exemplo h dois, o "carlos" e o "acs". Vamos tentar obter
ambos com o grep:
$ grep 'carlos' /etc/passwd
carlos:x:500:500:carlos:/home/carlos:/bin/bash
$ grep 'Carlos' /etc/passwd
acs:x:502:502:Antonio Carlos Silva:/home/acs:/bin/bash
$
tantos quantos se precise, mas em nosso caso apenas dois bastam, "C" e "c":
$ grep '[Cc]arlos' /etc/passwd
carlos:x:500:500:carlos:/home/carlos:/bin/bash
acs:x:502:502:Antonio Carlos Silva:/home/acs:/bin/bash
$
Repare bem no detalhe, toda a "lista" (os colchetes e seu contedo) vale para
apenas uma posio, um caractere. A ER "[Cc]arlos" serve para pesquisar por
"Carlos" e "carlos" ao mesmo tempo.
Dica n2: A lista, por maior que seja, representa apenas um caractere
Podemos combinar a lista com um dos metacaracteres j vistos, produzindo uma
ER mais poderosa:
$ grep '^[aeiou]' /etc/passwd
adm:x:3:4:adm:/var/adm:/sbin/nologin
uucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
ana:x:501:501:Ana Paula Moreira:/home/ana:/bin/bash
acs:x:502:502:Antonio Carlos Silva:/home/acs:/bin/bash
$
Este comando procura por usurios cujo login comece com uma vogal! Note o uso
do circunflexo para "amarrar" a pesquisa no incio da linha. Traduzindo essa ER,
fica: busque por linhas que comeam com a letra "a", ou "e", ou "i" ou "o" ou "u".
Para fazer o inverso e buscar as linhas que comeam com consoantes, a ER fica
bem mais comprida, pois necessrio especificar todas as letras:
$ grep '^[bcdfghjklmnpqrstvwxyz]' /etc/passwd
O ponto .
s vezes, necessrio permitir "qualquer" caractere numa certa posio. Por
exemplo, para procurar usurios onde a segunda letra do login seja uma vogal,
como "mario", e "jose", mas no "ana". No importa qual a primeira letra, pode ser
qualquer uma, mas a segunda deve ser uma vogal.
O ponto o metacaractere que significa "qualquer letra". E mais, na verdade ele
significa "qualquer caractere", pois alm de letras ele pode representar um nmero,
um smbolo, um TAB, enfim: qualquer caractere.
$ grep '^.[aeiou]' /etc/passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
news:x:9:13:news:/etc/news:
uucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
gopher:x:13:30:gopher:/var/gopher:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin
carlos:x:500:500:carlos:/home/carlos:/bin/bash
$
Esta expresso diz: " partir do comeo da linha, procure qualquer caractere
seguido de uma vogal".
O ponto tambm pode ser usado para se procurar por linhas de um tamanho fixo,
independente do seu contedo. Que tal se obter apenas as linhas que possuam
exatamente 27 caracteres?
$ grep '^...........................$' /etc/passwd
news:x:9:13:news:/etc/news:
$
Ser que ali tem 27 pontos mesmo? Como saber ao certo? Estranho isso de ficar
colocando vrios pontinhos n?
As chaves {}
Como Expresses Regulares so bacanas, elas facilitam este tipo de tarefa
tambm. Colocando um nmero entre chaves "{}", indicase uma quantidade de
repeties do caractere (ou metacaractere) anterior:
$ egrep '^.{27}$' passwd
news:x:9:13:news:/etc/news:
$
Essa expresso faz o mesmo que a anterior: procura por linhas que tenham 27
caracteres, quaisquer que sejam eles. A vantagem que basta olhar o nmero de
repeties, no precisa ficar contando os pontinhos.
Dica n3: .{27} igual a 27 pontos!
Note que foi usado o egrep e no o grep. porque as chaves fazem parte de um
conjunto avanado de Expresses Regulares ("extended"), ento o egrep lida
melhor com elas. Se fosse para usar o grep normal, teria que "escapar" as chaves:
$ grep '^.\{27\}$' /etc/passwd
Feio! Vamos usar somente o egrep daqui pra frente para evitar tais escapes.
As chaves ainda aceitam intervalos, sendo possvel informar uma faixa de
repeties vlidas, com mnimo e mximo. Para procurar por linhas que tenham de
20 a 40 caracteres:
$ egrep '^.{20,40}$' /etc/passwd
Se omitir o segundo nmero e manter a vrgula, fica uma faixa aberta, sem fim.
Assim pode se informar repeties de "no mnimo N vezes". Para obter as linhas
que possuem 40 caracteres ou mais:
$ egrep '^.{40,}$' /etc/passwd
E claro, essa repetio tambm pode ser usada para caracteres comuns ou outros
metacaracteres alm do ponto. Que tal repetir uma lista? Um bom exemplo
procurar os usurios que tm um UID ou GID de trs dgitos ou mais:
$ egrep '[0123456789]{3,}' /etc/passwd
games:x:12:100:games:/usr/games:/sbin/nologin
carlos:x:500:500:carlos:/home/carlos:/bin/bash
ana:x:501:501:Ana Paula Moreira:/home/ana:/bin/bash
acs:x:502:502:Antonio Carlos Silva:/home/acs:/bin/bash
$
O curinga .* (AND)
Quando se procura por dois trechos especficos numa mesma linha, no importando
o que h entre eles, usase o curinga ".*" para significar "qualquer coisa".
Um exemplo procurar os usurios que comeam com vogais e usam o shell bash:
$ egrep '^[aeiou].*bash$' /etc/passwd
ana:x:501:501:Ana Paula Moreira:/home/ana:/bin/bash
acs:x:502:502:Antonio Carlos Silva:/home/acs:/bin/bash
$
Ou seja, procuramos por uma linha que comece com uma vogal e termine com a
palavra "bash", no importando o que tem no meio, pode ser qualquer coisa. Essa
ER funcionou mais ou menos como um AND lgico, onde s casa se tiver as duas
pesquisas.
Dica n4: .* qualquer coisa, inclusive nada
9
O ou | (OR)
Para fazer o OR lgico, onde se procura por uma coisa ou outra, devese usar o
pipe "|" e delimitar as opes com os parnteses "()":
$ egrep '^(ana|carlos|acs):' /etc/passwd
carlos:x:500:500:carlos:/home/carlos:/bin/bash
ana:x:501:501:Ana Paula Moreira:/home/ana:/bin/bash
acs:x:502:502:Antonio Carlos Silva:/home/acs:/bin/bash
$
Essa ER casa apenas as linhas dos trs usurios citados. Ela comea procurando
no incio da linha "^", depois procura ou a palavra "ana", ou a palavra "carlos", ou a
palavra "acs", seguido pelo doispontos.
Os outros repetidores: ? * +
Outros metacaracteres que podem ser usados so o asterisco, o mais e a
interrogao (chamado opcional). Eles definem quantidades e funcionam como as
chaves, porm com uma sintaxe mais prtica:
Meta
Nome
Equivalente
Descrio
opcional
{0,1}
asterisco
{0,}
mais
{1,}
Como incmodo ter que colocar todas essas letras, tambm possvel "negar"
uma lista, especificando quais os caracteres que no so vlidos em uma posio.
Assim, para buscar as consoantes, podemos dizer "busque por linhas que no
comecem com vogais":
$ grep '^[^aeiou]' /etc/passwd
10
Veja como negar uma lista fcil! Caso o primeiro caractere dentro dos colchetes
seja um circunflexo, ele inverter o sentido dessa lista, tornandoa uma "lista
negada". Ela casar qualquer caractere, EXCETO os listados aps o "^".
Mas tenha cuidado, use a lista negada com cautela. Negar alguns caracteres
significa permitir todos os outros! Nmeros, smbolos, TAB e espao em branco
tambm fazem parte de "qualquer caractere exceto vogais". Em nosso exemplo
atual isso no atrapalha, mas tenha sempre em mente que essa negao bem
abrangente.
Dica n5: Ateno, negar uma lista significa permitir "todo o resto"
O intervalo em listas []
Outra facilidade da lista a possibilidade de se indicar intervalos, faixas. Basta
colocar um hfen entre duas letras que ele ser expandido para todas as letras
existentes no intervalo. Por exemplo "af" interpretado como "todas as letras
entre a e f, inclusive", ou seja "abcdef".
Reescrevendo o exemplo de procurar por nmeros de trs dgitos ou mais, que
tinha sido:
$ egrep '[0123456789]{3,}' /etc/passwd
Agora fica:
$ egrep '[09]{3,}' /etc/passwd
11
A tabela ASCII
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
!
"
#
$
%
&
'
(
)
*
+
,
.
/
0
1
2
3
4
5
6
7
8
9
:
;
<
=
>
?
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
@
A
B
C
D
E
F
G
H
I
J
K
L
M
N
O
P
Q
R
S
T
U
V
W
X
Y
Z
[
\
]
^
_
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
161
`
a
b
c
d
e
f
g
h
i
j
k
l
m
n
o
p
q
r
s
t
u
v
w
x
y
z
{
|
}
~
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
12
Nome
Posicionamento
[abc]
lista
[ad]
lista
[^abc]
(esse|aquele)
a{2}
chaves
a{2,4}
chaves
a{2,}
chaves
a?
opcional
a*
asterisco
a+
mais
ponto
.*
curinga
.*
{,} (|)
13
Escapar ou no escapar?
Dependendo do aplicativo, a sintaxe das ERs pode ser diferente da do egrep. No
sed e awk por exemplo (bem como no grep), as chaves e o "ou" devem ser
escapados para serem especiais.
Infelizmente a implementao de Expresses Regulares pelos programas uma
selva, e no tem como fugir do decoreba dessa tabela:
Programa opc mais chaves borda ou grupo
awk
()
egrep
{,}
\b
()
emacs
\b
\|
\(\)
find
\b
\|
\(\)
gawk
{,}
\<\>
()
grep
\?
\+
\{,\}
\b
\|
\(\)
sed
\?
\+
\{,\}
\<\>
\|
\(\)
vim
\=
\+
\{,}
\<\>
\|
\(\)
14
15