-
Notifications
You must be signed in to change notification settings - Fork 2
hernan604/Tutorial-Regex-PT-BR
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
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@algo.com Nome Completo ---- 02/02/1980 - 33 anooos --- email@algo.com Nome Completo --- 02/02/1980 ---- 33 aaanos ---- email@algo.com 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 email1@paragraph1.com 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 email2@paragraph2.com lacinia. Sed tempor nisl sit amet quam egestas posuere. Ut luctus email3@paragraph3.com ac turpis eget email4@paragraph4.com rhoncus. Nullam feugiat vehicula condimentum. Nunc et quam viverra, dignissim metus email5@paragraph5.com 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 email6@paragraph6.com 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 email7@paragraph7.com sed est sed, viverra posuere nulla. Ut semper facilisis odio eu tincidunt. email8@paragraph8.com 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 email9@paragraph9.com ipsum primis in faucibus. Nullam quis tortor in lorem ornare email10@paragraph10.com 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 email11@paragraph11.com 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 email12@paragraph12.com 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 email1@paragraph1.com 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 email2@paragraph2.com lacinia. Sed tempor nisl sit amet quam egestas posuere. Ut luctus email3@paragraph3.com ac turpis eget email4@paragraph4.com rhoncus. Nullam feugiat vehicula condimentum. Nunc et quam viverra, dignissim metus email5@paragraph5.com 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 email6@paragraph6.com 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 email7@paragraph7.com sed est sed, viverra posuere nulla. Ut semper facilisis odio eu tincidunt. email8@paragraph8.com 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 email9@paragraph9.com ipsum primis in faucibus. Nullam quis tortor in lorem ornare email10@paragraph10.com 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 email11@paragraph11.com 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 email12@paragraph12.com 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: acertos: myemail@bla.com meu-email@bla.com empresa@brasil.com.br 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 - mariana.da.silva@hotmail.com João Pereira ----- 22/11/1982 - 35 anooos --- joao.pereira@gmail.com Mariana Moura --- 07/02/1981 ---- 39 aaanos ---- mariana.moura@uol.com.br Trocar as posições e chegar em uma lista assim (email,nome,idade,data): mariana.da.silva@hotmail.com, Maria da Silva, 30 anos, 30/12/1970 joao.pereira@gmail.com, João Pereira, 35 anos, 22/11/1982 mariana.moura@uol.com.br, Mariana Moura, 39 anos, 07/02/1981 Solução: my $var = <<'END'; Maria da Silva - 30/12/1970 --- 30 anoos - mariana.da.silva@hotmail.com João Pereira ----- 22/11/1982 - 35 anooos --- joao.pereira@gmail.com Mariana Moura --- 07/02/1981 ---- 39 aaanos ---- mariana.moura@uol.com.br 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 - mariana.da.silva@hotmail.com João Pereira ----- 22/11/1982 - 35 anooos --- joao.pereira@gmail.com Mariana Moura --- 07/02/1981 ---- 39 aaanos ---- mariana.moura@uol.com.br 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: meu@nome.com nome.sobrenome50@sub.dominio.com.br Exemplo de emails incorretos: joao da silva@email.com ( tem espaços) joao@da@silva@email.com ( tem varios arrobas ) .joao.da.silva@email.com (comeca com ponto) joao@.email.com ( 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
About
Tutorial ensina o básico de regex com exemplos práticos
Resources
Stars
Watchers
Forks
Releases
No releases published
Packages 0
No packages published