-
Notifications
You must be signed in to change notification settings - Fork 2
/
README
625 lines (428 loc) · 32.6 KB
/
README
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
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
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
Regex Matching Manual do iniciante: O que são regexes, como funcionam e exemplos práticos
por: Hernan Lopes
O que são regexes
Regex servem para encontrar padrões dentro de strings.
Quando usar regex ?
Caso 1:
Listar todos os emails que aparecem no meio de um texto gigante
É fornecido um texto enorme com várias informações e no meio dessas informações são mencionados alguns emails.
Tarefa: Localizar e listar todos esses emails
Caso 2:
É fornecida uma lista com "nome - data aniversário - idade -- email"
Nome Completo -- 02/02/1980 --- 33 anoos - [email protected]
Nome Completo ---- 02/02/1980 - 33 anooos --- [email protected]
Nome Completo --- 02/02/1980 ---- 33 aaanos ---- [email protected]
A pessoa que digitava essa lista escrevia "anos" errado, e você tem que arrumar isso. Tem que transformar "anoos" em "anos", e , "aaaanos" em "anos" e assim sucessivamente.
Além disso é necessário mudar a ordem dos campos, agora vai ser:
"email, nome, idade, data aniversário"
OBS: perceba que os - (traços) as vezes se repetem 1 ou mais vezes
Caso 3:
Você tem em mãos um arquivo css, e precisa transformar em um objeto reutilizavel, ex:
Dada a lista:
body .languages-list .lang.c { background: background-position: -10px -410px; }
body .languages-list .lang.c-sharp { background: background-position: -20px -420px; }
body .languages-list .lang.cpp { background: background-position: -30px -430px; }
body .languages-list .lang.java { background: background-position: -40px -440px; }
body .languages-list .lang.perl { background: background-position: -50px -450px; }
body .languages-list .lang.python { background: background-position: -60px -460px; }
Transforme em objeto por exemplo, no caso da primeira linha:
{
'linguagem' : 'c',
'css' : 'background: background-position: -10px -410px;'
},
{
'linguagem' : 'c-sharp',
'css' : 'background: background-position: -20px -420px;'
}
etc...
Caso 4:
É dada um objeto com 1,000,000 atributos no seguinte formato:
Pessoa = {
nome : function(){},
sobrenome : function(){},
idade : function(){},
email : function(){},
}
E a tarefa é alinhar os atributos para ficarem mais próximos do ':', conforme exemplo a seguir:
Pessoa = {
nome: function(){},
sobrenome: function(){},
idade: function(){},
email: function(){},
}
Como identificar uma regex ?
Assim como as strings são representadas por "texto" ou 'texto'
Normalmente as regex são identificáveis por /regex/ ou /regex/substituicao/
No caso de // (duas barras)
Normalmente é utilizada para localizar padrões de texto dentro de um texto.
Exemplo de uso:
/joao/ vai procurar joao em uma string
/joao/i vai procurar joao em uma string, com case Insensitive (tratando maisculas e minusculas como similares)
/joao/ig vai procurar todas as ocorrências de joao dentro de uma string
m/joao/ig em perl, o m no começo indica que é pra fazer Match
No caso de /// (tres barras)
Normalmente é utilizada para fazer substituição. praticamente: /substituir isto/por isto/
s/texto ou regex para localizar/texto para substituir/ig
Exemplo de uso:
/isto/por aquilo/ substitui a primeira ocorrência
/isto/por aquilo/i case Insensitive
/isto/por aquilo/ig case Insensitive + global
s/isto/por aquilo/ig
Uso de regex para substituição te texto em perl:
$var = "Algum texto qualquer"
$var =~ s/Algum texto/Alguma regex/; #substituição
print $var:
Alguma regex qualquer
Uso de regex para localização de string em um texto em perl:
$var = "Algum texto qualquer";
print "encontrou texto" if $var =~ m/texto/ig;
Componentes de uma Regex:
[a-z] um caractere de minúsculo a até z
[A-Z] um caractere maiúsculo de A até Z
[0-9] um digito de 0 a 9
\w uma letra w é de word ( perceba que é w minúsculo )
\W qualquer coisa menos letra ( perceba que é W maiúsculo )
\s espaço
\S qualquer coisa menos espaço
\d um digito
\D qualquer coisa menos um digito
combinações são possíveis, ex:
[a-zA-Z] procura caracteres de a até z, minusculos e maiúsculos
[a-z0-9] procura de a até z minusculo ou digitos entre 0 e 9
[a-z0-9]+ procura um ou mais caracteres de a até z
minusculo ou digitos entre 0 e 9, por ex uma "palavra"
- Modificadores
/g (g)lobal matching
/i case (i)nsensitive search
/x e(x)tende permite adicionar comentarios na regex
/m permite procurar em strings (m)ultiline
- Metacharacteres
\ Escapa o próximo caractere, utilizado para procurar uma / por exemplo
^ Linha começando em
. Qualquer caractere exceto nova linha
$ Final da linha
| Ou
() Agrupamento
[] Caracretes dentro de colchetes
- Quantificadores
* 0 ou mais vezes
+ 1 ou mais vezes
? 1 ou 0 vezes (opcional)
{N} exatamente N vezes
{N,} pelo menos N vezes
{N,M} pelo menos N vezes mas não mais que M vezes
- Caracteres escapáveis
\t tab (HT, TAB)
\n nova linha (LF, NL)
\r return (CR)
\f form feed (FF)
\a alarm (bell) (BEL)
\e escape (think troff) (ESC)
\cK control char (example: VT)
\x{}, \x00 caractere cujo ordinah é um hexadecimal
\N{name} Nome de caractere Unicode ou sequência de caracteres
\N{U+263D} Caractere Unicode (ex: FIRST QUARTER MOON)
\o{}, \000 caractere cujo ordinal é um octal
\l minuscula
\u mauiscula
\L não maiuscula, incluindo outros caracteres
\U não minúscula, incluindo outros caracteres
- Captura de Grupos
(...)
(?<nome_do_grupo>...) e depois imprime com $+{nome_do_grupo}
A captura de grupos é vantajosa porque os grupos são armazenados em variáveis especiais que podem ser utilizadas após rodar a regex.
Funcionamento: Cada abertura de parentesis, conta +1, ex:
((.+)(.+))(.+) Aqui tenho 4 grupos, pois abre e fecham 4 parentesis
((.+)(.+)) Aqui tenho 3 grupos, pois abre e fecham 3 parentesis
|| |- terceiro parentesis abrindo = $3
||----- segundo parentesis abrindo = $2
|------ primeiro parentesis abrindo = $1
Essas são as variáveis especiais às quais eu me referi. $1, $2, $3 ...etc.. é o primeiro grupo, segundo grupo...
Outra opção é nomear a captura, isso permite acessar uma variável especial $+{nome_do_grupo}, ex:
(?<primeiro_grupo>(?<segundo_grupo>.+)(?<terceiro_grupo>.+)) é a mesma coisa que: ((.+)(.+))
e para imprimir o valor, é só fazer: $+{primeiro_grupo} que é bem mais prático
Exemplos rápidos
(.+) alguma coisa necessariamente com no mínimo 1 caractede
(.*) pode ter alguma coisa ou pode não ter
[^\/] não barra (escapei a barra) [^] significa não alguma coisa
([^\/]+)\/ tudo menos barra até chegar numa barra. Isso seria útil para
fazer match numa url por exemplo:
dominio.com.br/
essa url tem alguma coisa que não é barra, e só depois vem a barra.
com essa regex eu conseguiria extrair "dominio.com.br" que estaria
no grupo1 (primeiro parentesis)
Como localizar parentesis
O parentesis serve para criar grupos em regex, ex: (.+)
Mas como fazer para localizar parentesis no texto ?
É simples, apenas escape a regex, ex:
/algumacoisa (.+) e algo entre parentesis \((.+)\)/
o mesmo se aplica para todos os caracteres utilizados pela engine da regex.. é só escapar eles com 1 barra \
\.
\+
\)
\(
etc.
ex: perl -e ' $var = "aaaa++AA"; print 1 if $var =~ m/\+/; '
printa 1 se tiver um \+ em $var
e com o parentesis, um bom exemplo são os números de telefone:
(011) 2123-8928 =~ m/\((\d+)\) (\d+)-(\d+)/
$1 $2 $3 (grupos 1, 2 e 3 são os parentesis não escapados)
Regexes ineficientes
Assim como todo tipo de processamento, ele pode ser mais, ou menos eficiente.
Uma implementação mal planejada pode ter um custo bastante alto de processamento desnecessário.
Por exemplo, se planeja encontrar a extensão de um arquivo, pode tomar uma vantagem tendo em vista que a extensão sempre está no final do nome do arquivo.
Então você faz uma regex, por exemplo:
m/\.(\w{3,4})$/g Que vai procurar um . (ponto) seguido de 3 até 4 caracteres, no final da linha! Ou seja,
ja vai começar a procurar pelo final da linha... e caso não utilize a opção $ (final da linha)
a regex será processada a partir do início, e isso pode aumentar o tempo no processamento se
houver muitas strings a serem processadas.
Se a pessoa que está implementando a regex se sentir insegura, ela pode sempre utilizar o
serviço de um bom debugador de regex interativo e assim a pessoa vê o passo a passo
da análise da regex.
Como debugar uma regex
Para debugar uma regex, você pode utilizar o:
Regexp::Debugger
http://search.cpan.org/~dconway/Regexp-Debugger-0.001013/lib/Regexp/Debugger.pm
Regex nos editores de texto
Os editores de texto mais comuns, vim, emacs, textmate, sublime, todos tem suporte a regex.
Problemas do dia a dia:
Solução para o Caso 1:
Dado o texto abaixo, encontrar todos os emails nele contidos:
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse tincidunt ligula in accumsan congue. Fusce vel accumsan libero. Sed eget libero quis sapien hendrerit tristique id ut justo. Phasellus imperdiet, nulla eu pulvinar porta, purus enim condimentum diam, in posuere dolor nibh porta nibh. Vestibulum ante ipsum primis [email protected] in faucibus orci luctus et ultrices posuere cubilia Curae; Maecenas a sapien in sem condimentum convallis. Vivamus ac libero nibh.
Mauris malesuada augue semper, varius erat at, ornare erat. Fusce laoreet neque odio, a malesuada dolor adipiscing ac. Vestibulum vel euismod tortor. Nulla facilisi. Cras commodo ligula ut sapien adipiscing, id porttitor arcu eleifend. Pellentesque ac fermentum quam, eu varius sapien. Etiam ornare aliquet ante sit amet [email protected] lacinia. Sed tempor nisl sit amet quam egestas posuere. Ut luctus [email protected] ac turpis eget [email protected] rhoncus. Nullam feugiat vehicula condimentum. Nunc et quam viverra, dignissim metus [email protected] adipiscing, iaculis dolor. Donec nisl erat, lobortis vel facilisis ac, viverra eget nunc. Maecenas iaculis dictum dui, accumsan viverra lectus blandit quis.
Phasellus pellentesque tellus a lacus condimentum dapibus. Sed euismod rhoncus felis vitae elementum. Cras vel vehicula tellus. Quisque iaculis diam a convallis facilisis. Nullam a ligula lacus. Morbi varius eleifend scelerisque. Integer nisl ligula, volutpat scelerisque dictum sed, cursus eget nisl. Nam non accumsan nunc. Pellentesque condimentum hendrerit nunc, sit amet dapibus urna tempus in.
Vivamus nibh felis, consequat a arcu id, tincidunt pharetra quam. Nullam hendrerit dolor vitae turpis volutpat ornare. Cras non elit vel lorem vulputate vulputate. Vivamus placerat velit eu enim rhoncus tincidunt. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam nibh libero, accumsan sit amet accumsan et, semper et nisi. Proin malesuada lacus nec volutpat scelerisque. Mauris sit amet ante sed lorem ornare tempus ut sit amet nisi. Mauris quis cursus diam, id accumsan nisi. Vivamus ultricies purus ligula, vel dapibus lorem fringilla sed. Morbi at laoreet [email protected] dui, id sagittis sem. Phasellus vel tristique nulla. Nam vitae egestas justo. Ut porta mollis nibh non commodo.
Fusce leo urna, feugiat suscipit blandit non, tempus at magna. Nam mauris velit, scelerisque [email protected] sed est sed, viverra posuere nulla. Ut semper facilisis odio eu tincidunt. [email protected] Morbi et ante dolor. Morbi commodo libero euismod, lobortis nibh eu, malesuada lectus. Vivamus gravida at dui at gravida. Etiam malesuada quis elit fermentum iaculis. Sed non enim vel urna accumsan condimentum tempus eu elit.
Phasellus quis dignissim dolor, vel tristique mauris. Praesent tempus lorem sed ipsum condimentum viverra. Pellentesque ut dolor eget augue venenatis bibendum at quis libero. Interdum et malesuada fames ac ante [email protected] ipsum primis in faucibus. Nullam quis tortor in lorem ornare [email protected] mollis. Curabitur aliquet lacinia tincidunt. Sed congue tristique sem mattis ullamcorper. Donec vitae adipiscing mi. Sed vitae eros eget leo fringilla interdum nec id lacus. Donec ut nisi condimentum, rutrum lectus in, dictum eros. Etiam et tincidunt purus, sed viverra mi. Quisque vitae dui nisl. Aenean sit amet nunc nec lorem venenatis bibendum. Cras fringilla pellentesque dui et rhoncus.
Etiam varius venenatis tempor. Cras aliquet, metus et mollis accumsan, risus leo elementum elit, sit amet fringilla dolor nisl ac metus. Suspendisse lacinia nunc a volutpat egestas. Fusce vitae feugiat nunc. Proin imperdiet aliquet nunc, sed lacinia velit viverra ac. Suspendisse egestas suscipit [email protected] lacus, et placerat est consectetur at. Curabitur eleifend felis in nulla fermentum luctus id vitae augue. Maecenas et sem sit amet felis pharetra porttitor. Duis tristique urna vel turpis ultrices pulvinar. Mauris nec adipiscing massa. Nam eu ante erat. Suspendisse aliquet mi nec eros pharetra aliquam eget quis libero.
Nunc dignissim orci a tellus suscipit ultricies. Donec lacinia semper dapibus. Pellentesque tincidunt, dolor in malesuada sagittis, odio velit adipiscing nisl, non lacinia massa magna ut felis. Phasellus semper tristique fringilla. Ut non nulla gravida, sollicitudin est eget, tempor sapien. Suspendisse condimentum augue non nisi dictum, in condimentum enim tempus. Nulla pharetra metus blandit luctus commodo. Aenean eget mauris a massa elementum ornare quis vel ipsum.
Quisque et pulvinar neque, nec porta turpis. Proin ac justo vel augue sollicitudin tempus id quis erat. In tortor sem, bibendum id leo non, ullamcorper aliquet augue. Sed adipiscing vitae diam ac malesuada. Integer dapibus rutrum lorem sed auctor. Vivamus nisl sapien, facilisis at nisi eu, feugiat pretium tortor. Nullam luctus feugiat gravida. Fusce quis euismod risus. Vestibulum augue diam, commodo eget lorem in, vehicula ornare eros. Etiam sollicitudin, dui ac ornare dignissim, metus elit viverra arcu, ut sagittis massa est id dolor.
Duis et nibh non neque dignissim venenatis et eu odio. Vivamus sit amet blandit ante. Fusce cursus aliquet arcu, eget hendrerit velit egestas nec. Mauris scelerisque, arcu eget consectetur pulvinar, leo orci malesuada augue, vitae porttitor ligula enim fermentum libero. Nam vehicula urna sit amet est porttitor congue. Cras [email protected] condimentum felis et ligula commodo accumsan. Praesent volutpat interdum dolor eu feugiat. Aliquam vel elit laoreet, sagittis mauris sed, cursus velit.
Solução com perl:
my $texto = <<'END';
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse tincidunt ligula in accumsan congue. Fusce vel accumsan libero. Sed eget libero quis sapien hendrerit tristique id ut justo. Phasellus imperdiet, nulla eu pulvinar porta, purus enim condimentum diam, in posuere dolor nibh porta nibh. Vestibulum ante ipsum primis [email protected] in faucibus orci luctus et ultrices posuere cubilia Curae; Maecenas a sapien in sem condimentum convallis. Vivamus ac libero nibh.
Mauris malesuada augue semper, varius erat at, ornare erat. Fusce laoreet neque odio, a malesuada dolor adipiscing ac. Vestibulum vel euismod tortor. Nulla facilisi. Cras commodo ligula ut sapien adipiscing, id porttitor arcu eleifend. Pellentesque ac fermentum quam, eu varius sapien. Etiam ornare aliquet ante sit amet [email protected] lacinia. Sed tempor nisl sit amet quam egestas posuere. Ut luctus [email protected] ac turpis eget [email protected] rhoncus. Nullam feugiat vehicula condimentum. Nunc et quam viverra, dignissim metus [email protected] adipiscing, iaculis dolor. Donec nisl erat, lobortis vel facilisis ac, viverra eget nunc. Maecenas iaculis dictum dui, accumsan viverra lectus blandit quis.
Phasellus pellentesque tellus a lacus condimentum dapibus. Sed euismod rhoncus felis vitae elementum. Cras vel vehicula tellus. Quisque iaculis diam a convallis facilisis. Nullam a ligula lacus. Morbi varius eleifend scelerisque. Integer nisl ligula, volutpat scelerisque dictum sed, cursus eget nisl. Nam non accumsan nunc. Pellentesque condimentum hendrerit nunc, sit amet dapibus urna tempus in.
Vivamus nibh felis, consequat a arcu id, tincidunt pharetra quam. Nullam hendrerit dolor vitae turpis volutpat ornare. Cras non elit vel lorem vulputate vulputate. Vivamus placerat velit eu enim rhoncus tincidunt. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam nibh libero, accumsan sit amet accumsan et, semper et nisi. Proin malesuada lacus nec volutpat scelerisque. Mauris sit amet ante sed lorem ornare tempus ut sit amet nisi. Mauris quis cursus diam, id accumsan nisi. Vivamus ultricies purus ligula, vel dapibus lorem fringilla sed. Morbi at laoreet [email protected] dui, id sagittis sem. Phasellus vel tristique nulla. Nam vitae egestas justo. Ut porta mollis nibh non commodo.
Fusce leo urna, feugiat suscipit blandit non, tempus at magna. Nam mauris velit, scelerisque [email protected] sed est sed, viverra posuere nulla. Ut semper facilisis odio eu tincidunt. [email protected] Morbi et ante dolor. Morbi commodo libero euismod, lobortis nibh eu, malesuada lectus. Vivamus gravida at dui at gravida. Etiam malesuada quis elit fermentum iaculis. Sed non enim vel urna accumsan condimentum tempus eu elit.
Phasellus quis dignissim dolor, vel tristique mauris. Praesent tempus lorem sed ipsum condimentum viverra. Pellentesque ut dolor eget augue venenatis bibendum at quis libero. Interdum et malesuada fames ac ante [email protected] ipsum primis in faucibus. Nullam quis tortor in lorem ornare [email protected] mollis. Curabitur aliquet lacinia tincidunt. Sed congue tristique sem mattis ullamcorper. Donec vitae adipiscing mi. Sed vitae eros eget leo fringilla interdum nec id lacus. Donec ut nisi condimentum, rutrum lectus in, dictum eros. Etiam et tincidunt purus, sed viverra mi. Quisque vitae dui nisl. Aenean sit amet nunc nec lorem venenatis bibendum. Cras fringilla pellentesque dui et rhoncus.
Etiam varius venenatis tempor. Cras aliquet, metus et mollis accumsan, risus leo elementum elit, sit amet fringilla dolor nisl ac metus. Suspendisse lacinia nunc a volutpat egestas. Fusce vitae feugiat nunc. Proin imperdiet aliquet nunc, sed lacinia velit viverra ac. Suspendisse egestas suscipit [email protected] lacus, et placerat est consectetur at. Curabitur eleifend felis in nulla fermentum luctus id vitae augue. Maecenas et sem sit amet felis pharetra porttitor. Duis tristique urna vel turpis ultrices pulvinar. Mauris nec adipiscing massa. Nam eu ante erat. Suspendisse aliquet mi nec eros pharetra aliquam eget quis libero.
Nunc dignissim orci a tellus suscipit ultricies. Donec lacinia semper dapibus. Pellentesque tincidunt, dolor in malesuada sagittis, odio velit adipiscing nisl, non lacinia massa magna ut felis. Phasellus semper tristique fringilla. Ut non nulla gravida, sollicitudin est eget, tempor sapien. Suspendisse condimentum augue non nisi dictum, in condimentum enim tempus. Nulla pharetra metus blandit luctus commodo. Aenean eget mauris a massa elementum ornare quis vel ipsum.
Quisque et pulvinar neque, nec porta turpis. Proin ac justo vel augue sollicitudin tempus id quis erat. In tortor sem, bibendum id leo non, ullamcorper aliquet augue. Sed adipiscing vitae diam ac malesuada. Integer dapibus rutrum lorem sed auctor. Vivamus nisl sapien, facilisis at nisi eu, feugiat pretium tortor. Nullam luctus feugiat gravida. Fusce quis euismod risus. Vestibulum augue diam, commodo eget lorem in, vehicula ornare eros. Etiam sollicitudin, dui ac ornare dignissim, metus elit viverra arcu, ut sagittis massa est id dolor.
Duis et nibh non neque dignissim venenatis et eu odio. Vivamus sit amet blandit ante. Fusce cursus aliquet arcu, eget hendrerit velit egestas nec. Mauris scelerisque, arcu eget consectetur pulvinar, leo orci malesuada augue, vitae porttitor ligula enim fermentum libero. Nam vehicula urna sit amet est porttitor congue. Cras [email protected] condimentum felis et ligula commodo accumsan. Praesent volutpat interdum dolor eu feugiat. Aliquam vel elit laoreet, sagittis mauris sed, cursus velit.
END
while ( $texto =~ m/(([^\s]+)@([^\s]+))/gx ) {
my $email = $1;
print $email,"\n";
}
Essa regex não é a melhor regex para email, fiz ela simples apenas para exemplificar o problema. A explicação a seguir:
(([^\s]+)\@([^\s]+)) quer dizer:
(([^\s]+) qualquer coisa que não seja espaço, mas tem acertos e falhas ex:
falhas: myemail@a ;myemail@b \myemail[@l
Ou seja, esses emails todos iriam ser aceitos como match para esta regex.
Isso prova que ela não é tão eficiente para detectar emails incorretos
@ obrigatoriamente um email
([^\s]+)) qualquer coisa que não seja espaço
O ideal seria usar [A-Z0-9._%+-]+@(?:[A-Z0-9-]+\.)+[A-Z]{2,4}
Alguns serviços ainda fazem um ping no domínio para rerificar se tem uma máquina ativa no domínio especificado no email
Solução para o Caso 2:
Dada uma lista gigante assim:
Maria da Silva - 30/12/1970 --- 30 anoos - [email protected]
João Pereira ----- 22/11/1982 - 35 anooos --- [email protected]
Mariana Moura --- 07/02/1981 ---- 39 aaanos ---- [email protected]
Trocar as posições e chegar em uma lista assim (email,nome,idade,data):
[email protected], Maria da Silva, 30 anos, 30/12/1970
[email protected], João Pereira, 35 anos, 22/11/1982
[email protected], Mariana Moura, 39 anos, 07/02/1981
Solução:
my $var = <<'END';
Maria da Silva - 30/12/1970 --- 30 anoos - [email protected]
João Pereira ----- 22/11/1982 - 35 anooos --- [email protected]
Mariana Moura --- 07/02/1981 ---- 39 aaanos ---- [email protected]
END
print $var;
my $new_var;
while ( $var =~ m/(.+) -{1,} (\d{2}\/\d{2}\/\d{4}) -{1,} (\d+) [a]{1,}[n]{1,}[o]{1,}[s]{1,} -{1,} (.+)/g ) {
$new_var .= "$4, $1, $3 anos, $4\n";
}
print $new_var;
Explicação da regex utilizada:
Dadas as linhas de texto que eu vou analisar, eu preciso encontrar um padrão entre elas para poder desenvolver minha regex
ou seja, ao visualizar o texto:
Maria da Silva - 30/12/1970 --- 30 anoos - [email protected]
João Pereira ----- 22/11/1982 - 35 anooos --- [email protected]
Mariana Moura --- 07/02/1981 ---- 39 aaanos ---- [email protected]
eu consigo chegar na seguinte analise: O texto começa com um nome, depois é seguido de tracinhos (no mínimo 1 tracinho) e
logo na sequencia vem datas no formato dd/mm/yyyy e depois vem um ou mais tracinhos seguidos da idade, que é um ou mais
digitos seguido da palavra anos que está mal escrita. e depois mais tracinhos e depois um email que tem uma arroba.
Com esse pensamento em mente eu consigo desenvolver uma regex por exemplo a regex abaixo:
(.+) -{1,} (\d{2}\/\d{2}\/\d{4}) -{1,} (\d+) [a]{1,}[n]{1,}[o]{1,}[s]{1,} -{1,} (.+)
que quer dizer:
(.+) alguma coisa
-{1,} no mínimo 1 traço
(\d{2}\/\d{2}\/\d{4}) formato da data (2 digitos/2digitos/4digitos)
-{1,} no mínimo 1 traço
(\d+) um ou mais digitos ( representa a idade )
[a]{1,}[n]{1,}[o]{1,}[s]{1,} palavra anos que pode estar escrita com 1 ou mais a, 1 ou mais n, 1 ou mais o e 1 ou mais s
-{1,} no mínimo 1 traço
(.+) alguma coisa, neste caso sempre vai ser o email que esta logo após a data
Solução Caso 3:
Você tem em mãos um arquivo css, e precisa transformar em um objeto reutilizavel, ex:
Dada a lista:
body .languages-list .lang.c { background: background-position: -10px -410px; }
body .languages-list .lang.c-sharp { background: background-position: -20px -420px; }
body .languages-list .lang.cpp { background: background-position: -30px -430px; }
body .languages-list .lang.java { background: background-position: -40px -440px; }
body .languages-list .lang.perl { background: background-position: -50px -450px; }
body .languages-list .lang.python { background: background-position: -60px -460px; }
Transforme em objeto por exemplo, no caso da primeira linha:
{
'linguagem' : 'c',
'css' : 'background: background-position: -10px -410px;'
},
{
'linguagem' : 'c-sharp',
'css' : 'background: background-position: -20px -420px;'
}
etc...
Solução, simples, utilize uma regex que captura:
body .languages-list .lang.(nome da linguagem antes de aparecer um espaço)(seguido de espaços){ background: background-position: -(valor2)px -(valor2)px; }
o que resulta em uma regex como esta por exemplo:
body .languages-list .lang.(?<linguagem>[^\s]+)(\s*){ (?<css_stuff>\d+) }
solução em perl oneliner:
perl -e ' my $var = "body .languages-list .lang.c { background: background-position: -10px -410px; }"; \
if ( $var =~ m/body .languages-list .lang.(?<linguagem>[^\s]+)(\s*){ (?<css_stuff>.+)n\"css\": \"$+{css_stuff}\",\n\"linguagem\": \"$+{linguagem}\"\n}"; } '
SAIDA:
{
"css": "background: background-position: -10px -410px;",
"linguagem": "c"
}
Caso 4:
É fornecido um objeto pessoa e sua tarefa é deixar ele mais bonitinho... alinhando os atributos para a direita, para ficarem mais proximos dos dois pontos.
Pessoa = {
nome : function(){},
sobrenome : function(){},
idade : function(){},
email : function(){},
}
Solução opção 1: Fazer manualmente
Solução opção 2: Utilizar a regex: s/(\s+)([^ ]+)(\s+):/\1\3\2:/
Que nada mais é que:
s/
(\s+) primeiro vem espaços (captura de grupo $1)
([^ ]+) depois vem coisas que não são espaços (captura de grupo $2)
(\s+) e depois vem espaços denovo (captura de grupo $3)
: e depois vem um dois pontos
/
\1 substitua pelo captura $1.. no caso são os espaços que antecedem os atributos
\3 coloque a captura $3, que são os espaços que sucedem os atributos
\2 e agora sim coloque a captura $2, que é o atributo
: e depois coloque um dois pontos...
/
ao final vc vai ter um objeto com no seguinte formato
Pessoa = {
nome: function(){},
sobrenome: function(){},
idade: function(){},
email: function(){},
}
Exemplo 3 - Validar email:
Vamos supor que você tem uma ficha de cadastro onde a pessoa entra com um email.
Você não pode aceitar emails nitidamente inválidos. Por exemplo, emails não tem espaço, não tem acento.
Exemplos de emails válidos:
Exemplo de emails incorretos:
joao da [email protected] ( tem espaços)
joao@da@[email protected] ( tem varios arrobas )
[email protected] (comeca com ponto)
[email protected] ( dominio comeca com ponto )
Então é possível analisar alguns casos e chegar em um padrão para identificar emails nitidamente incorretos. (do ponto de vista da escrita do email)
Uma regex que pode verificar isso é a recomendada pelo site:
http://www.regular-expressions.info/email.html
A regex: [A-Z0-9._%+-]+@(?:[A-Z0-9-]+\.)+[A-Z]{2,4}
Explicacao:
[A-Z0-9._%+-]+
@
(?:[A-Z0-9-]+\.)+
[A-Z]{2,4}
Exemplo de uso da regex de email:
$email = "sdodsj\@jdos.com";
if ( $email =~ m/[A-Z0-9._%+-]+@(?:[A-Z0-9-]+\.)+[A-Z]{2,4}/gi ) {
print "yes"
}
Exemplo 4: Como retirar acentos de uma string com perl e transliteração ?
my $str = "áééáouiÁ~-23eáé" ;
$str =~ tr/àáâãäçèéêëìíîïñòóôõöùúûüýÿÀÁÂÃÄÇÈÉÊËÌÍÎÏÑÒÓÔÕÖÙÚÛÜÝ/aaaaaceeeeiiiinooooouuuuyyAAAAACEEEEIIIINOOOOOUUUUY/ ;
print $str
SAIDA: aaaoaoaaouiaY~-23eaaao
Isso é perl, temos os:
m// para fazer (m)atch
s/// para fazer (s)ubstituição
tr/// para fazer (tr)ansliteração
Transliteração: Trocar todas as ocorrências dos caracteres encontrados na lista de busca,
pelos caracteres corresondentes na lista de substituição.
Ou seja, no caso acima, a regex vai pegar um ç e substituir por c que é o caractere correspondente no lado direito da regex.
Como criar e debugar uma regex ?
Um dos jeitos é setar a string numa variável, ex:
$texto = "0210301203 Tutorial-Regex-PT-BR 2013 Hernan Lopes"
e depois fazer match pra chegar no que vc precisa, ex: (se quisesse pegar o nome desse texto)
print $+{nome} #imprime o grupo de captura "nome"
if ( $texto =~ m/(?<id>\d+) (?<titulo>.+) (?<ano>\d+) (?<nome>.+)/ )
e no perl é fácil fazer isso em uma linha, direto no shell, com o comando:
perl -e '$texto = "0210301203 Tutorial-Regex-PT-BR 2013 Hernan Lopes" ; print $+{nome} if ( $texto =~ m/(?<id>\d+) (?<titulo>.+) (?<ano>\d+) (?<nome>.+)/ )'
Erros comuns
Fazer match cegamente sem analisar os possíveis pontos de falha
Suponha que é dado o nome de um arquivo de imagem, e é necessário descobrir o tamanho do thumb desse arquivo:
alto-paraiso-300x300.jpg <- o tamanho fica antes da extensão
natacao-4x100meters-blablabla-300x300.png <- tamanho antes da extensão, mas tem 4x100 metros,
* no caso natacao: será que a regex vai se confundir dependendo de como ela é pensada ?
Supondo que o thumbnail está sempre no final do arquivo, antes da extensão,
é possível fazer, incorretamente, da seguinte maneira:
Maneira1: utilizando a regex: /(?<tamanho_thumb>\d+x\d+)/
if ( "alto-paraiso-300x300.jpg" =~ m/(?<tamanho_thumb>\d+x\d+)/ ) {
print $+{tamanho_thumb}
}
SAIDA: 300x300 (correto)
if ( "natacao-4x100meters-blablabla-300x300.png" =~ m/(?<tamanho_thumb>\d+x\d+)/ ) {
print $+{tamanho_thumb}
}
SAIDA: 4x100 (INcorreto, deveria ser 300x300)
Motivo: A regex utilizada não é global, e portanto vai encontrar o primeiro \d+x\d+ que encontrar e vai retornar como resultado
Veja as capturas encontradas utilizando essa regex:
$var = "natacao-4x100meters-blablabla-300x300.png" ;
use Data::Printer;
warn p @capturas if ( @capturas = $var =~ m/(?<tamanho_thumb>\d+x\d+)+?/g )
[
[0] "4x100", <--- encontrou 2 padrões que se encaixam na regex
[1] "300x300" <--- esta é a que preciso, o último!
]
Maneira2: Então uma das maneiras para arrumar isso seria:
$var = "natacao-4x100meters-blablabla-300x300.png" ;
use Data::Printer;
warn @capturas[ scalar( @capturas ) - 1 ] # total de capturas encontradas, menos 1,
# ou seja: a última captura encontrada
if ( @capturas = $var =~ m/(?<tamanho_thumb>\d+x\d+)/g )
SAIDA: 300x300 (que seria o correto)
tendo em vista que thumbnail está sempre no final do arquivo, antes da extensão,
tambem seria possível criar uma regex que pega o tamanho do thumb proximo
do final do arquivo.
Maneira4: Utilizando uma regex por exemplo, assim:
/(\d+x\d+)\.[a-zA-Z]{3,4}$/
Que seria:
(\d+x\d+) Primeiro grupo: 1 ou mais digitos seguido de x seguido de 1 ou mais diditos
\. depois vem um ponto obrigatório
[a-zA-Z]{3,4} verifica se tem 3 a 4 caracteres de a-z minúsculo ou A-Z maiúsculo
boa pois as extensoes tem 3 a 4 caracteres..ex: jpg jpeg png gif bmp
$ procura no final da linha
Na prática:
$var = "natacao-4x100meters-blablabla-300x300.png";
warn $+{tamanho_thumb}
if ( $var =~ m/(?<tamanho_thumb>\d+x\d+)\.[a-zA-Z]{3,4}$/g ) #é a regex acima
A dica é, pensar nas outras possibilidades... é necessário prever a maior possibilidade de casos possíveis.
As vezes a regex não é a prova de balas mas atende a necessidade.
A regex jamais deve ser incoerente com seu propósito.
REFERENCES:
http://perldoc.perl.org/perlre.html
http://www.regular-expressions.info/email.html