-
Notifications
You must be signed in to change notification settings - Fork 11
/
expressoes-regulares.html
195 lines (182 loc) · 17.4 KB
/
expressoes-regulares.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
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
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
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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
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
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en-us">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>Expressões Regulares</title>
<meta name="author" content="" />
<!--- Blueprint CSS Framework -->
<link rel="stylesheet" href="css/blueprint/screen.css" type="text/css" media="screen, projection">
<link rel="stylesheet" href="css/blueprint/print.css" type="text/css" media="print">
<!--[if IE]>
<link rel="stylesheet" href="css/blueprint/ie.css" type="text/css" media="screen, projection">
<![endif]-->
<!-- CodeRay syntax highlighting CSS -->
<link rel="stylesheet" href="css/coderay.css" type="text/css" />
<!-- Homepage CSS -->
<link rel="stylesheet" href="css/site.css" type="text/css" media="screen, projection" />
</head>
<body>
<div class="container">
<div class="column span-22 prepend-1 append-1 first last" id="header">
<h1 class="title"><a href="index.html" alt="voltar para o início">Tutorial de Ruby do GURU-SP</a></h1>
<hr>
</div>
<div class="column span-17 prepend-1 first">
<p class="title">Expressões Regulares</p>
<p>Expressões regulares, embora críticas, são uma poderosa ferramenta para trabalhar com texto. O Ruby possui esta funcionalidade incluída em seu núcleo. Elas são usadas para o casamento de padrões e processamento de texto.</p>
<p>Muitas pessoas acham que expressões regulares são difíceis de usar, difíceis de ler, de manter e, consequentemente, improdutivas. Você pode acabar usando apenas um pequeno número de expressões regulares em suas aplicações em Ruby e Rails. Não é pré-requisito, para programar em Rails, tornar-se um especialista em Expressões Regulares. Entretanto, é recomendado o aprendizado, ao menos o básico de como as expressões regulares funcionam.</p>
<p><b>Uma expressão regular é uma forma simples de especificar um padrão de caracteres que será casado com uma string</b>. Em Ruby, você normalmente cria uma expressão regular escrevendo um padrão entre caracteres de barra ‘/’ (/padrão/). Em Ruby, expressões regulares são objetos (do tipo <b>Regexp</b>) e podem ser manipulados como tais. <b>//</b> é uma expressão regular e uma instância da classe Regexp, como demonstrado abaixo:</p>
<div class="CodeRay">
<pre><span class="no">1</span> <span class="rx"><span class="dl">/</span><span class="dl">/</span></span>.class <span class="c"># Regexp</span>
</pre>
</div>
<p>Você pode escrever um padrão que casa com uma cadeia de caracteres contendo o texto Pune ou o texto Ruby usando a seguinte expressão regular:</p>
<div class="CodeRay">
<pre><span class="no">1</span> <span class="rx"><span class="dl">/</span><span class="k">Pune|Ruby</span><span class="dl">/</span></span>
</pre>
</div>
<p>Caracteres de barra (‘/’) delimitam o padrão, que consistem em dois padrões que serão casados, separados por um caractere de pipe (|). O caractere pipe (|) significa “ou o padrão que está a direita ou o padrão que está a esquerda”, neste caso <i>Pune ou Ruby</i>.</p>
<p>A forma mais simples de verificar se há um padrão que case entre uma expressão regular e uma cadeia de caracteres é o método <b>match/</b>. Você pode fazer isso em qualquer direção: objetos Regexp e objetos String, ambos respondem ao método <b>match</b>. Se não houver casamento entre os padrões, o método retorna <b>nil</b>. Se houver um casamento de padrão, é retornado uma instância da classe <b>MatchData</b>. Podemos utilizar o operador <b>=~</b> para casar uma cadeia de caracteres contra uma expressão regular. Caso o padrão seja encontrado, <b>=~</b> retorna a posição em que o padrão foi encontrado, caso contrário retorna <b>nil</b>.</p>
<div class="CodeRay">
<pre><span class="no">1</span> m1 = <span class="rx"><span class="dl">/</span><span class="k">Ruby</span><span class="dl">/</span></span>.match(<span class="s"><span class="dl">"</span><span class="k">O futuro eh Ruby</span><span class="dl">"</span></span>)
<span class="no">2</span> puts m1.class <span class="c"># retorna MatchData</span>
<span class="no">3</span> m2 = <span class="s"><span class="dl">"</span><span class="k">O futuro eh Ruby</span><span class="dl">"</span></span> =~ <span class="rx"><span class="dl">/</span><span class="k">Ruby</span><span class="dl">/</span></span>
<span class="no">4</span> puts m2 <span class="c"># retorna 14</span>
</pre>
</div>
<p>Os possíveis componentes de uma expressão regular incluem os seguintes:</p>
<h2>Caracteres literais</h2>
<p>Qualquer caractere literal que for adicionado em uma expressão regular casa consigo mesmo na string.</p>
<div class="CodeRay">
<pre><span class="no">1</span> <span class="rx"><span class="dl">/</span><span class="k">a</span><span class="dl">/</span></span>
</pre>
</div>
<p>Esta expressão regular casa com a cadeia de caracteres “a”, assim como qualquer cadeia de caracteres que contenha a letra “a”.</p>
<p>Alguns caracteres têm significado especial para o parser de expressões regulares. Quando você quer casar algum desses caracteres especiais, você tem que escapá-lo com o caractere de barra-invertida (\). Por exemplo, para casar o caractere ? (interrogação), você deve escrever isto:</p>
<div class="CodeRay">
<pre><span class="no">1</span> <span class="rx"><span class="dl">/</span><span class="ch">\?</span><span class="dl">/</span></span>
</pre>
</div>
<p>A barra-invertida significa “não considere o próximo caractere como especial, trate-o como ele mesmo.”</p>
<p>Os caracteres especiais incluem ^, $, ? , ., /, \, [, ], {, }, (, ), +, e *.</p>
<h2>O caractere coringa . (ponto)</h2>
<p>Algumas vezes você irá querer casar qualquer caractere em algum ponto do seu padrão. Isto é feito utilizando o caractere coringa . (ponto). Um ponto casa com qualquer caractere exceto o caractere de nova linha (\n). Esta expressão regular:</p>
<div class="CodeRay">
<pre><span class="no">1</span> <span class="rx"><span class="dl">/</span><span class="k">.ejected</span><span class="dl">/</span></span>
</pre>
</div>
<p>casa, ao mesmo tempo, com “dejected” e “rejected”. Também casa com “%ejected” e “8jected”. O caractere coringa é muito útil, mas algumas vezes ele casa com mais padrões do que o desejado. Entretanto, você pode impor condições no casamento de padrões enquanto permite o casamento de múltiplas cadeias de caracteres, usando classes de caracteres.</p>
<h2>Classes de Caracteres</h2>
<p>Uma classe de caractere é uma lista explicita de caracteres, colocada entre colchetes em uma expressão regular:</p>
<div class="CodeRay">
<pre><span class="no">1</span> <span class="rx"><span class="dl">/</span><span class="k">[dr]ejected</span><span class="dl">/</span></span>
</pre>
</div>
<p>Isto significa “case d ou r, seguido de ejected”. Este novo padrão casa tanto com “dejected” ou “rejected”, mas não com “&ejected”. Uma classe de caracteres é um tipo de caractere quase coringa: elas possibilitam múltiplos caracteres em uma posição na expressão regular, mas apenas um número limitado de caracteres.</p>
<p>Em uma classe de caracteres, você pode, inclusive, incluir um intervalo de caracteres. Um uso comum desses intervalos é a classe para letras minúsculas:</p>
<div class="CodeRay">
<pre><span class="no">1</span> <span class="rx"><span class="dl">/</span><span class="k">[a-z]</span><span class="dl">/</span></span>
</pre>
</div>
<p>Para casar um dígito hexadecimal, você pode usar mais de um intervalo em uma classe de caracteres:</p>
<div class="CodeRay">
<pre><span class="no">1</span> <span class="rx"><span class="dl">/</span><span class="k">[A-Fa-f0-9]</span><span class="dl">/</span></span>
</pre>
</div>
<p>Esta classe casa com qualquer caractere de a à f (maiúsculo ou minúsculo) ou qualquer dígito.</p>
<p>Algumas vezes você precisa casar qualquer caratere exceto aqueles que estão em uma lista especial. Você pode, por exemplo, verificar se o primeiro caractere em uma string não é um dígito hexadecimal válido.</p>
<p>Você cria esse tipo de “busca negativa” negando uma classe de caracteres. Para fazer isso, você coloca um caractere de acento circunflexo (^) no comeco da classe. Aqui está a classe que casa com qualquer caractere exceto aqueles que são digitos hexadecimais válidos:</p>
<div class="CodeRay">
<pre><span class="no">1</span> <span class="rx"><span class="dl">/</span><span class="k">[^A-Fa-f0-9]</span><span class="dl">/</span></span>
</pre>
</div>
<p>Algumas classes de caracteres são tão comuns que possuem abreviações especiais.</p>
<h2>Sequencias especiais de escape para classes de caracteres comuns</h2>
<p>Para casar qualquer digito você pode fazer assim:</p>
<div class="CodeRay">
<pre><span class="no">1</span> <span class="rx"><span class="dl">/</span><span class="k">[0-9]</span><span class="dl">/</span></span>
</pre>
</div>
<p>Mas você pode fazer a mesma coisa de forma mais concisa com a sequência especial de escape \d:</p>
<div class="CodeRay">
<pre><span class="no">1</span> <span class="rx"><span class="dl">/</span><span class="ch">\d</span><span class="dl">/</span></span>
</pre>
</div>
<p>Outras duas sequencias de escape predefinidas bastante úteis são:<br />
\w que casa qualquer dígito, caractere alfabético ou caractere de underscore (_).<br />
\s que casa qualquer caractere de espaço em branco (espaço, tabulação, linha nova).</p>
<p>Cada uma dessas classes predefinidas possui sua forma negada. Você pode casar qualquer caractere que não seja um dígito fazendo isto:</p>
<div class="CodeRay">
<pre><span class="no">1</span> <span class="rx"><span class="dl">/</span><span class="ch">\D</span><span class="dl">/</span></span>
</pre>
</div>
<p>Da mesma forma, \W casa com qualquer caractere que não seja alfabético ou underscore, e \S casa com qualquer caractere que não seja espaço em branco.</p>
<p>Sempre que um padrão casa um objeto <b>MatchData</b> é retornado.</p>
<p>Toda operação de casamento pode ser bem sucedida ou falhar. Vamos iniciar pelo caso mais simples: a falha. Quando você tentar casar uma string com um padrão, e não houver casamento, o resultado é sempre <b>nil</b>:</p>
<div class="CodeRay">
<pre><span class="no">1</span> <span class="rx"><span class="dl">/</span><span class="k">a</span><span class="dl">/</span></span>.match(<span class="s"><span class="dl">"</span><span class="k">b</span><span class="dl">"</span></span>) <span class="c"># nil</span>
</pre>
</div>
<p>Este <b>nil</b> funciona como falso ou “sem resposta” quando um casamento de padrão é tratado como um teste verdadeiro/falso.</p>
<p>Diferentemente de <b>nil</b>, um objeto <b>MatchData</b> retornado por um casamento bem sucedido é tratado como um valor Booleano verdadeiro, que torna simples os teste de casamento/não casamento. Além disso, o objeto <b>MatchData</b> retornado armazena os dados do casamento, possibilitando que você possa verificá-los com os métodos apropriados: onde o casamento iniciou (em qual caractere na string), quanto do padrão casou na string, o que foi capturado nos agrupamentos entre parênteses, e outras coisas mais.</p>
<p>Para utilizar o objeto <b>MatchData</b>, você precisa, primeiramente, armazená-lo. Considere um exemplo em que gostaríamos de extrair um número de telefone de uma string e armazenar suas diferentes partes (código de área, operadora, número) em partes. Exemplo <b>p064regexp.rb</b></p>
<div class="CodeRay">
<pre><span class="no"> 1</span> <span class="c"># p064regexp.rb</span>
<span class="no"> 2</span> string = <span class="s"><span class="dl">"</span><span class="k">Meu telefone é (123) 555-1234.</span><span class="dl">"</span></span>
<span class="no"> 3</span> phone_re = <span class="rx"><span class="dl">/</span><span class="ch">\(</span><span class="k">(</span><span class="ch">\d</span><span class="k">{3})</span><span class="ch">\)</span><span class="ch">\s</span><span class="k">+(</span><span class="ch">\d</span><span class="k">{3})-(</span><span class="ch">\d</span><span class="k">{4})</span><span class="dl">/</span></span>
<span class="no"> 4</span> m = phone_re.match(string)
<span class="no"> 5</span> <span class="r">unless</span> m
<span class="no"> 6</span> puts <span class="s"><span class="dl">"</span><span class="k">Não houve casamento...</span><span class="dl">"</span></span>
<span class="no"> 7</span> exit
<span class="no"> 8</span> <span class="r">end</span>
<span class="no"> 9</span> print <span class="s"><span class="dl">"</span><span class="k">Toda a string com que começamos: </span><span class="dl">"</span></span>
<span class="no"><strong>10</strong></span> puts m.string
<span class="no">11</span> print <span class="s"><span class="dl">"</span><span class="k">Toda a parte da string que foi casada: </span><span class="dl">"</span></span>
<span class="no">12</span> puts m[<span class="i">0</span>]
<span class="no">13</span> puts <span class="s"><span class="dl">"</span><span class="k">As três capturas: </span><span class="dl">"</span></span>
<span class="no">14</span> <span class="i">3</span>.times <span class="r">do</span> |index|
<span class="no">15</span> puts <span class="s"><span class="dl">"</span><span class="k">Captura #</span><span class="il"><span class="idl">#{</span>index + <span class="i">1</span><span class="idl">}</span></span><span class="k">: </span><span class="il"><span class="idl">#{</span>m.captures[index]<span class="idl">}</span></span><span class="dl">"</span></span>
<span class="no">16</span> <span class="r">end</span>
<span class="no">17</span> puts <span class="s"><span class="dl">"</span><span class="k">Outro jeito de conseguir a primeira captura:</span><span class="dl">"</span></span>
<span class="no">18</span> print <span class="s"><span class="dl">"</span><span class="k">Captura #1: </span><span class="dl">"</span></span>
<span class="no">19</span> puts m[<span class="i">1</span>]
</pre>
</div>
<p>Neste código, nós usamos o método <b>string</b> do objeto <b>MatchData</b> (<b>puts m.string</b>) para obter toda string em que a operação <b>match</b> foi executada. Para obter as partes da string que casaram com nosso padrão, nós adicionamos os índices do objeto <b>MatchData</b> entre colchetes, com o valor 0 no índice. Também usamos o método times (<b>3.times do |index|</b>) para iterar exatamente 3 vezes com o bloco de código e imprimir os subcasamentos (as capturas entre parenteses) sucessivamente. Dentro do bloco de código o método chamado <b>captures</b> extrai as substrings que casam com a parte do padrão que está entre parênteses. Finalizando, nós exibimos novamente a primeira captura, mas dessa vez utilizamos uma técnica diferente: indexamos o objeto <b>MatchData</b> diretamente com colchetes e inteiros positivos, cada inteiro correspondendo a uma captura.</p>
<p>Aqui está a saída:</p>
<div class="CodeRay">
<pre><span class="no"> 1</span> >ruby p064regexp.rb
<span class="no"> 2</span> Toda a string com que começamos: Meu telefone é (123) 555-1234.
<span class="no"> 3</span> Toda a parte da string que foi casada (123) 555-1234
<span class="no"> 4</span> As três capturas:
<span class="no"> 5</span> Captura #1: 123
<span class="no"> 6</span> Captura #2: 555
<span class="no"> 7</span> Captura #3: 1234
<span class="no"> 8</span> Outro jeito de conseguir a primeira captura:
<span class="no"> 9</span> Capture #1: 123
<span class="no"><strong>10</strong></span> >Exit code: 0
</pre>
</div>
<p>Leia o <a href="http://www.regular-expressions.info/ruby.html" title="em inglês">tutorial de expressões regulares do site Regular-Expressions.info</a>, para mais detalhes quanto à expressões regulares na linguagem Ruby.</p>
<p>Uma boa aplicação para testar suas expressões regulares é o <a href="http://www.rubular.com">Rubular.com</a>.</p>
<p>O tópico acima foi adaptado do livro <a href="http://www.manning.com/black/">Ruby for Rails</a>.</p>
<div class="pagination"><a href="escrevendo-sua-propria-classe.html">Escrevendo sua própria classe ></a></div>
</div>
<div class="column span-5 append-1 last">
<p><a href="http://www.gurusp.org" title="Grupo de Usuários Ruby de SP"><img src="images/logo_guru-sp.jpg" title="Logo do GURU-SP" alt="Logo do Guru-SP" /></a></p>
<div class="box">
<p>Este material tem como base o <a href="http://www.rubylearning.com" title="Ruby Learning">tutorial do RubyLearning.com de Satish Talim</a> e foi traduzido por membros do <a href="http://www.gurusp.org" title="Grupo de Usuários Ruby de SP">GURU-SP</a> com a permissão do autor.</p>
<p class="last">Ajude o RubyLearning participando em algum dos <a href="http://www.rubylearning.org" title="cursos do Ruby Learning">cursos pagos</a> ou <a href="http://pledgie.com/campaigns/415" title="Ajude o Ruby Learning">fazendo uma doação para o projeto</a></p>
</div>
<p class="quiet"><a href="index.html" title="índice">Voltar para o índice</a></p>
<h5></h5>
<p class="incr"></p>
</div>
<div class="column span-22 prepend-1 append-1 first last" id="footer">
<hr />
<p>Tuturial de Ruby do <a href="http://www.gurusp.org" title="Grupo de Usuários Ruby de SP">GURU-SP</a>. Este site foi criado com <a href="http://webby.rubyforge.org">Webby</a></p>
</div>
</div>
</body>
</html>