You are on page 1of 18

TUTORIAL CGI-BIN

CGI/Perl: O Incio Perl uma linguagem de programao, e CGI um protocolo de comunicao (um cdigo) atravs do qual o servidor HTTP (ou servidor web) intermedia a transferncia de informaes entre um programa (no mesmo computador que o servidor) e um cliente HTTP (o seu browser). No correto falar "eu quero um CGI que faa tal coisa", mas sim "eu quero um programa que use CGI e faa tal coisa", ou de maneira mais curta "eu quero um programa CGI que faa tal coisa" ou "eu quero um script que faa tal coisa". Um script no implica em CGI, mas scripts Perl (programas Perl) tornaram-se to comuns em se tratando de CGI, que falar script j quer dizer "programa CGI escrito em Perl". sempre bom lembrar que um programa CGI pode ser feito em qualquer linguagem usada no mesmo computador que o servidor, no s em Perl. Mas o status alcanado por Perl devido a suas qualidades para tarefas associados a CGI e por sua portabilidade. 1. Um programa simples A primeira linha Comentrios e declaraes Imprimindo na tela 2. Executando o programa 3. Variveis escalares Operaes e Atribuies Interpletao Exerccio 4. Variveis de matrizes Atribuies de matrizes Mostrando matrizes Exerccio 5. Manipulando arquivos Exerccio 6. Estruturas de controle foreach Testando for

while e until Exerccio

7. Condicionais Exerccio 8. Comparando strings Expresses regulares A varivel especial $_ Mais sobre ERs Alguns exemplos de ERs Exerccio 9. Substituio e traduo Opes Recordando modelos Traduo Exerccios 10. Split Exerccio 11. Matrizes associativas Operadores Variavis de Ambiente 12. Subrotinas Parmetros Retornado Valores Variveis Locais Um programa simples Aqui est um programa simples que usaremos para comearmos: #!/usr/local/bin/perl print 'Ol mundo.'; # mostra uma mensagem Cada parte ser discutida a seguir. A primeira linha Todo programa escrito em Perl deve sempre comear com esta linha: #!/usr/local/bin/perl Contudo, ela pode variar de sistema para sistema. Esta linha indica para o servidor o que fazer com o arquivo quando ele executado (i., rodar o programa atravs do Perl) e informa a localizao exata do compilador. Comentrios e declaraes Comentrios podem ser inseridos em um programa atravs do smbolo #, e qualquer coisa aps ele, at o final da linha, ignorado (com exceo da primeira linha). A nica maneira de usar comentrios longos colocando # no incio de cada linha. Toda declarao em Perl deve terminar com um ponto-e-vrgula, como na ltima linha do programa acima. Imprimindo na tela A primeira funo exibe informaes. No caso acima, ele mostra a cadeia de caracteres Ol mundo. Este resultado ser mostrado somente se for executado na linha de comandos. Para que a mesma informao seja mostrada pelo seu browser, voc deve modificar o programa, de forma que a mensagem seja reconhecida pelo formato HTML ou como texto simples.

print "Content-type: text/html\n\n"; print 'Ol mundo.'; O prximo passo rod-lo.

# informa ao browser

# mostra a mensagem simples, sem formatao

Executando o programa Digite o programa acima em um editor de texto, depois salve ele. Existem duas formas de instalar seu programa no servidor: Pelo Unix (requer conhecimento bsico), Emacs um bom editor porque possui o modo Perl que formata linhas facilmente quando voc pressiona tab (use M-x perl-mode). Pelo FTP, use qualquer editor de texto puro, e envie o arquivo atravs de um programa de FTP (CuteFTP ou WS_FTP), importante que seja usado o modo de transferncia ASCII, e nunca Binrio. O programa deve ser salvo com a extenso .cgi (que indica ser um script) ou com .pl (de Perl), e depois torn-lo executvel. Pelo Unix, digite: chmod u+x programa na linha de comandos, onde programa o nome do seu arquivo. Pelo FTP, clique em alterar atributos do arquivo, escolhendo o valor 755 (-rwxr-xr-x). Agora rode o programa apenas digitando um destes comandos: perl programa (pelo DOS ou UNIX) ./programa (pelo UNIX) programa (pelo DOS) Caso voc esteja usando a linha de comandos do DOS, necessrio ter o programa Perl for Win32 instalado, ele pode ser retirado no endereo: http://www.activestate.com/ Se algo ocorrer de errado, podem aparecer mensagens de erro, ou nada. Voc pode sempre rodar o programa com mensagens atravs do comando: perl -w programa Ele mostrar avisos e outras mensagens de ajuda antes de tentar executar o programa. Para rod-lo com a depurao, use o comando: perl -d programa O Perl compila primeiro o programa e ento executa sua verso compilada. Assim, aps uma pequena pausa para compilao, o programa deve rodar rapidamente. Certifique-se de que o programa est funcionando antes de continuar. Variveis escalares O tipo mais usado de varivel no Perl o escalar. Variveis escalares podem conter caracteres e/ou nmeros, e note que eles so completamente intercambiveis. Por exemplo, a declarao: $prioridade = 9; atribui a varivel escalar $prioridade o valor 9, mas voc pode tambm designar uma string (cadeia de caracteres) para a mesma varivel: $prioridade = 'alta'; Perl tambm aceita nmeros como strings: $prioridade = '9'; $default = '0009'; e ainda pode realizar operaes aritmticas ou outras. Em geral, nomes de variveis consistem de nmeros, letras e smbolos _ mas no devem comear com nmeros depois do $. A varivel $_ especial, como veremos mais tarde. Alm disso, o Perl case sensitive, i., letras maisculas so diferentes de minsculas, por exemplo, $a e $A so variveis distintas. Operaes e Atribuies Interpletao Exerccio Operaes e Atribuies O Perl utiliza todas as operaes usuais na linguagem C: $a = 1 + 2; # soma 1 e 2 e armazena em $a $a = 3 - 4; # subtrai 4 de 3 e armazena em $a

$a = 5 * 6; # multiplica 5 por 6 $a = 7 / 8; # divide 7 por 8 e retorna 0.875 $a = 9 ** 10; # 9 elevado por 10 $a = 5 % 2; # resto da diviso de 5 por 2 ++$a; # incrementa $a e retorna seu valor $a++; # retorna $a e depois incrementa em 1 --$a; # decrementa $a e retorna seu valor $a--; # retorna $a e depois decrementa em 1 e para caracteres, existem os seguintes operadores: $a = $b . $c; # concatena $b e $c $a = $b x $c; # $b repetido $c vezes Para atribuir valores, Perl utiliza: $a = $b; # atribui $b para $a $a += $b; # soma $b para $a $a -= $b; # subtrai $b de $a $a .= $b; # acrescenta $b em $a Note que quando Perl atribui um valor como $a = $b, ele faz uma cpia de $b e ento o atribui para $a. Portanto, na prxima vez que voc alterar $b, ele no ir alterar $a. Outras operaes podem ser encontradas atravs do comando man perlop na linha de comandos do Unix. Interpletao O seguinte cdigo mostra mas e pras usando concatenao: $a = 'mas'; $b = 'pras'; print $a.' e '.$b; Seria mais fcil incluir somente uma string no final da declarao print, mas a linha: print '$a e $b'; mostra somente $a e $b, e no mas e pras, o que no o nosso caso. Ao invs disso, podemos usar aspas duplas no lugar de aspas simples: print "$a e $b"; Estas aspas foram a interpolao de qualquer cdigo, incluindo interpretao de variveis. Isso mais apropriado que nossa declarao original. Outros cdigos que so interpolados incluem caracteres como newline e tab. O cdigo \n o newline (enter/return) e \t o tab. Outros exemplos que produzem o mesmo resultado: print ' Meu e-mail nome@dominio.com '."\n"; print " Meu e-mail nome\@dominio.com \n"; Note que, com aspas duplas, se faz necessrio o uso da barra invertida antes do @, porque seno ele ser interpretado como sendo uma varivel, que veremos adiante. Exerccios Neste exerccio voc deve reescrever seu primeiro programa de modo que (1) a string seja atribuda para uma varivel e (2) esta varivel seja impressa com um caractere newline. Use as aspas duplas e no utilize o operador de concatenao. Certifique-se de que o programa funciona, antes de prosseguir. Variveis de matrizes Um tipo mais interessante de varivel o de matrizes (vetores) que uma lista de variveis escalares. Variveis de matrizes tem o mesmo formato das escalares exceto que eles so prefixados pelo smbolo @. As declaraes: @comida = ("mas", "pras", "uvas"); @musica = ("flauta", "gaita"); atribuem trs elementos para a matriz @comida e dois para a matriz @musica. A matriz acessada pelo uso de ndices comeando do zero, e colchetes so usados para especificar cada ndice. A expresso: $comida[2] retorna uvas. Note que o smbolo @ foi mudado para $ porque uvas o valor de uma varivel escalar. Atribuies de matrizes Mostrando matrizes Exerccio

Atribuies de matrizes No Perl, a mesma expresso em um contexto diferente pode produzir um resultado diferente. A primeira atribuio abaixo expande a varivel @musica de modo que fique equivalente segunda atribuio: @mais_musica = ("rgo", @musica, "harpa"); @mais_musica = ("rgo", "flauta", "gaita", "harpa"); Isto deve sugerir um modo de acrescentar elementos em uma matriz. Um modo simples de acrescentar estes elementos usar a declarao: push(@comida, "ovos"); que acrescenta ovos ao fim da matriz @comida. Para acrescentar dois ou mais itens, use um dos seguintes formatos: push(@comida, "ovos", "carne"); push(@comida, ("ovos", "carne")); push(@comida, @mais_comida); http://www.microsoft.co Alm disso, a funo push retorna o comprimento da nova lista. m/brasil/ie50/http://www. Para remover o ltimo item de uma lista e retorn-lo, use a funo pop. De microsoft.com/brasil/ie50 nossa primeira lista, a funo pop retorna uvas e @comida passa a ter dois elementos: / $outra_comida = pop(@comida);# agora $outra_comida = http://www.netscape.com/"uvas" computing/download/indeTambm possvel atribuir uma matriz para uma varivel escalar. A linha: $c = @comida; x.html? cp=hom05tdowhttp://ww atribui apenas o comprimento de @comida, mas w.netscape.com/computin$c = "@comida"; g/download/index.html? transforma a lista em uma string com um espao entre cada elemento. Este espao pode ser substitudo por qualquer outro caractere apenas mudando cp=hom05tdow o valor da varivel especial $" (por exemplo, $" = " mais ";). Esta varivel apenas uma de muitas outras usadas na linguagem Perl. Matrizes tambm podem ser usadas para fazer mltiplas atribuies para variveis escalares: ($a, $b) = ($c, $d); # o mesmo que $a=$c; $b=$d; ($a, $b) = @comida; # $a e $b so os primeiros itens de @comida. ($a, @alguma_comida) = @comida; # $a o primeiro item de @comida e @alguma_comida uma lista dos # demais elementos. (@alguma_comida, $a) = @comida; # @alguma_comida = @comida e $a indefinida. A ltima atribuio ocorre desta maneira porque matrizes consomem tudo, e @alguma_comida retira todos os elementos de @comida. Portanto, este formato deve ser evitado. Finalmente, voc pode querer encontrar o ndice do ltimo elemento de uma lista. Para fazer isso, use a expresso: $#comida

Copyright 1999 STI Internet. Todos os direitos reservados.

Mostrando matrizes Desde que contexto importante, no surpresa que os seguintes comandos produzem resultados diferentes: print @comida; # resultado bvio print "@comida"; # tratado como string print @comida.""; # em um contexto escalar Exerccios Experimente cada uma das trs declaraes citadas em "Mostrando matrizes" para ver o que elas fazem. Manipulando arquivos Aqui est um programa bsico em Perl que faz o mesmo que o comando cat do Unix em um certo arquivo: #!/usr/local/bin/perl # # Programa para abrir o arquivo de senhas, ler, # escrever, e fech-lo. $arquivo = '/etc/passwd'; # nome do arquivo open(INFO, $arquivo); # abre o arquivo @linhas = ; # coloca ele em uma matriz close(INFO); # fecha o arquivo print @linhas; # exibe a matriz A funo open abre um arquivo para entrada (i., para leitura). O primeiro parmetro o nome que permite ao Perl referir o arquivo futuramente. O segundo parmetro a expresso denotando o nome do arquivo com sua localizao. Se o nome do arquivo for escrito entre aspas, ento ele tomado literalmente sem a expanso shell do Unix. Assim, a expresso '~/etc/passwd' no ser interpretada com sucesso. Se voc deseja forar a expanso shell, ento use os smbolos < e >, neste caso, <~/etc/passwd>. A funo close diz ao Perl para fechar o arquivo. Existem poucos pontos para acrescentar sobre a manipulao de arquivos. Primeiro, a declarao open pode tambm especificar um arquivo para sada ou para acrscimo, assim como para entrada. Para fazer isso, use o smbolo > para sada e >> para acrscimos: open(INFO, $arquivo); # abre para leitura open(INFO, ">$arquivo"); # abre para escrita open(INFO, ">>$arquivo"); # permite acrescentar open(INFO, "<$arquivo"); # tambm abre para leitura Segundo, se voc quiser gravar alguma informao em um arquivo, voc deve abri-lo para escrita e ento pode usar a declarao print com um parmetro extra. Para gravar uma string no arquivo INFO use: print INFO "Esta linha vai para o arquivo.\n"; Terceiro, voc pode usar o seguinte comando para abrir a entrada padro (usualmente o teclado) e a sada padro (usualmente a tela) respectivamente: open(INFO, '-'); # abre entrada padro open(INFO, '>-'); # abre sada padro No programa acima, a informao lida do arquivo. O arquivo chamase INFO e para ler ele atravs do Perl, coloque entre os smbolos < e >. Assim, a declarao: @linhas = <INFO>;

l o arquivo denotado por INFO e coloca dentro da matriz @linhas. Note que a expresso <INFO> l o arquivo inteiro em apenas um passo. Isto ocorre porque a leitura tratada como uma varivel de matriz. Se @linhas fosse substituda por uma varivel escalar $linhas, ento somente a primeira linha seria lida (e depois as prximas). Em ambos casos, cada linha armazenada completamente com seu caractere newline no final. Exerccio Exerccio #!/usr/local/bin/perl # # Programa para abrir o arquivo de senhas, ler, # escrever, e fech-lo. $arquivo = '/etc/passwd'; # nome do arquivo open(INFO, $arquivo); # abre o arquivo @linhas = ; # coloca ele em uma matriz close(INFO); # fecha o arquivo print @linhas; # exibe a matriz Modifique o programa acima de modo que todo o arquivo contenha o smbolo # no incio de cada linha. Voc dever somente acrescentar uma linha e modificar uma delas. Use a varivel $". Coisas inesperadas podem ocorrer com arquivos, ento voc pode encontrar alguma ajuda com o uso da opo w, como mencionado no tpico Executando o programa.

Estruturas de controle Possibilidades mais interessantes aparecem quando ns introduzimos as estruturas de controle e o looping. Perl suporta muitos tipos diferentes de estruturas de controle que tendem a ser como na linguagem C, mas muitos so similares aos do Pascal, tambm. Aqui discutiremos um pouco delas. foreach Testando for while e until Exerccio foreach Para executar cada linha de uma matriz ou de outra estrutura com formato de lista (como linhas em um arquivo), Perl usa a estrutura foreach. Ela tem o seguinte formato: foreach $petisco (@comida) # visitar cada item e coloc-lo em $petisco { print "$petisco\n"; # exibe cada item print "Yum yum\n"; # de @comida... } As aes a serem realizadas cada vez, esto no bloco entre chaves. Na primeira passagem pelo bloco, $petisco atribudo ao valor do primeiro item da matriz @comida. Na prxima vez, ele atribudo ao segundo valor, e assim por diante. Se @comida estiver vazio logo no incio, ento o bloco de declaraes no ser executado. Testando As prximas e poucas estruturas contam com os testes booleanos verdadeiro ou falso. O nmero zero, sendo zero um caractere, e o caractere vazio ("") so contados como falsos. Aqui esto alguns testes em nmeros e strings: $a == $b # $a numericamente igual a $b? cuidado: no use s o operador = $a != $b $a numericamente diferente de $b?

$a eq $b # $a uma string igual a $b? $a ne $b # $a uma string diferente de $b? Voc pode tambm tentar usar operadores lgicos e, ou, no: ($a && $b) # $a e $b so verdadeiros? ($a || $b) # $a ou $b verdadeiro? !($a) # $a falso? for Perl possui a estrutura for que funciona da mesma forma que no C. Ele tem o formato: for (inicializar; testar; incrementar) { primeira_ao; segunda_ao; etc; } Primeiramente, a declarao inicializar executada. Ento, enquanto testar for verdadeiro, o bloco de aes ser executado. Aps cada passagem, a vez de incrementar. Aqui est um exemplo de loop para mostrar os nmeros de 0 a 9: for ($i = 0; $i < 10; ++$i) # comea com $i = 0 # executa enquanto $i < 10 # incrementa $i antes de repetir # neste caso $i++ tem o mesmo efeito { print "$i\n"; } while e until Aqui est um programa que l do teclado e no continua at que a senha correta seja digitada: #!/usr/local/bin/perl print "Senha? "; # pede pela senha $a = <STDIN>; # l do teclado chop $a; # remove o newline no final da linha while ($a ne "teste") # enquanto a senha estiver errada... { print " errada.\n Senha? "; # solicita novamente $a = <STDIN>; # l do teclado chop $a; # remove o caractere newline no final } O bloco de cdigo entre chaves executado enquanto a entrada no for igual a senha. A estrutura while deve ser de fcil compreenso, mas oportuno notar diversos detalhes. Primeiro, ns podemos ler de uma entrada padro (teclado) sem precisar abri-la. Segundo, quando a senha digitada, $a inclui o caractere newline no final (ao pressionar enter/return). A funo chop remove o ltimo caractere de uma string que neste caso o newline. Para testar o oposto, ns podemos usar a declarao until do mesmo modo. Este executa o bloco repetidamente at que a expresso seja verdadeira, e no enquanto ela verdadeira. Outra tcnica til, colocar o while ou until no final do bloco de declaraes, em vez de colocar no incio. Isto requer a presena do operador do para marcar o incio do bloco e o teste no final. Novamente, o programa acima pode ento ser escrito desta forma (note que o bloco ser executado pelo menos uma vez): #!/usr/local/bin/perl do { print "Senha? "; # pede pela senha $a = ; # l do teclado chop $a; # remove o ltimo caractere, newline }

while ($a ne "teste"); # repete enquanto a senha for errada # usando until no lugar de while, # until ($a eq "teste"); repete at que a senha esteja correta Exerccio Modifique o programa do exerccio anterior de modo que cada linha do arquivo seja lida uma a uma, e retorne com um nmero de linha no incio. Voc deve ter algo como: 1 root:oYpYXm/qRO6N2:0:0:Super-User:/:/bin/csh 2 sysadm:*:0:0:System V Administration:/usr/admin:/bin/shdiag:*:0:996:Hardware Diagnostics:/usr/diags:/bin/csh 3 etc Talvez seja interessante usar esta estrutura: while ($linha = ) # l cada linha at o final de INFO { ... } Quando voc tiver feito isso, veja se pode alter-lo de modo que cada nmero de linha seja mostrada como 001, 002, ..., 009, 010, 011, 012, etc. Para fazer isso, voc dever somente mudar uma linha inserindo quatro caracteres extras. Lembre-se que o Perl permite isso. Condicionais claro que o Perl tambm permite testes condicionais if/then/else. Eles possuem o seguinte formato: if ($a) { print "A varivel no est vazia\n"; } else { print "A varivel est vazia\n"; } Para entender, recorde que o caractere vazio considerado como falso. Ele tambm retorna falso se o caractere for zero. Tambm possvel incluir mais alternativas em uma declarao condicional: if (!$a) # ! o operador no { print "A varivel est vazia\n"; } elsif (length($a) == 1) # se acima falir, tente isso { print "A varivel tem um caractere\n"; } else # se tambm falir... { print "A varivel tem vrios caracteres\n"; } Neste caso, importante notar que a declarao elsif est correta, sem o e de elseif. Exerccio

Exerccio Encontre um arquivo grande com algum texto e algumas linhas em branco. Do exerccio anterior, voc deve ter um programa que mostra o arquivo de senhas com nmeros de linhas. Mude ele de modo que funcione com o outro arquivo de texto. Agora altere o programa de modo que aqueles nmeros no sejam mostrados ou contados com linhas em branco, mas toda linha permanece sendo mostrada, incluindo as em branco. Recorde que, quando uma linha do arquivo lida, ela continua incluindo seu caractere newline no final. Comparando strings Um dos mais teis recursos do Perl (seno o mais til) a poderosa manipulao de strings. No corao desta, est a expresso regular (ER) que compartilhada por muitos outros utilitrios do Unix. Expresses regulares A varivel especial $_ Mais sobre ERs Alguns exemplos de ERs Exerccio Expresses regulares Uma expresso regular sempre est contida entre barras, e a comparao ocorre com o operador =~. A seguinte expresso verdadeira se a string aparecer na varivel $sentena: $sentenca =~ /para/ A ER case sensitive, de modo que se: $sentenca = "Para as raposas"; ento a comparao resultar em falsa. O operador !~ usado para o oposto, sendo assim o exemplo: $sentenca !~ /para/ retorna verdadeiro porque a string no aparece em $sentena A varivel especial $_ Ns podemos usar uma condicional como: if ($sentenca =~ /sob/) { print "Ns estamos conversando\n"; } que dever mostrar a mensagem se tivermos um dos seguintes valores: $sentenca = "Embaixo e sob"; $sentenca = " sobre o assunto..."; Porm mais frequentemente e muito mais fcil se atribuirmos a sentena uma varivel especial $_ (certamente escalar). Se ns fizermos isso, ento podemos evitar o uso dos operadores de comparao e o exemplo acima pode ser escrito como: if (/sob/) { print "Ns estamos conversando\n"; } A varivel $_ padro para muitas operaes do Perl e tende a ser muito usado. Mais sobre ERs Em uma ER existe uma grande quantidade de caracteres especiais, o que faz com que parea mais complicado. O melhor modo de construir seus programas usando ERs aos poucos. Aqui esto alguns caracteres especiais ER e seus significados: . # qualquer caractere exceto newline ^ # o incio da linha ou do caractere $ # o fim da linha ou do caractere * # nenhum, um ou mais do ltimo caractere + # um ou mais do ltimo caractere ? # nenhum ou o ltimo caractere e aqui alguns exemplos de comparaes. Recorde que seu uso sempre entre barras. p.r # p seguido por qualquer caractere seguido por e # isto ir comparar: # par # para

# por ^f # f no incio da linha ^ftp # ftp no incio da linha es$ # es no final da linha und* # un seguido por nenhum ou vrios caracteres d # isto ir comparar: # un # und # undd # unddd (etc) .* # qualquer string sem o newline, # isto ocorre porque o . compara qualquer caractere # e o * o mesmo que nenhum ou mais deste caractere ^$ # uma linha vazia Existem ainda mais opes. Colchetes podem ser usados para comparar qualquer um destes caracteres dentro deles. Entre colchetes, o smbolo - indica entre e o smbolo ^ no incio significa no: [qjk] # tanto q ou j ou k [^qjk] # exceto q, j e k [a-z] # qualquer um entre a e z, inclusive estes [^a-z] # exceto letras minsculas [a-zA-Z] # qualquer letra [a-z]+ # qualquer sequncia com pelo menos uma ou mais letras minsculas As demais opes servem mais para referncia. Uma barra vertical | representa ou e os parnteses podem ser usados para agrupar caracteres: gelia|creme # tanto gelia ou creme (ov|dad)os # tanto ovos ou dados (da)+ # tanto da ou dada ou dadada Aqui esto mais alguns caracteres especiais: \n # um newline \t # um tab \w # qualquer caractere alfanumrico (palavra) # o mesmo que [a-zA-Z0-9_] \W # exceto caracteres alfanumricos, # o mesmo que [^a-zA-Z0-9_] \d # qualquer dgito # o mesmo que [0-9] \D # exceto dgitos, [^0-9] \s # qualquer caractere em branco: espao, # tab, newline, etc \S # exceto caracteres em branco \b # uma palavra limitada, fora de [] \B # nenhuma palavra limitada Est claro que caracteres como $, |, [, ), \, / so casos particulares em expresses regulares. Se voc quiser comparar um ou mais destes caracteres, ento deve sempre preced-los de uma barra invertida: \| # barra vertical \[ # colchetes esquerdo \) # parnteses direito \* # asterisco \^ # circunflexo \/ # uma barra \\ # barra invertida Alguns exemplos de ERs Como foi mencionado antes, o uso de expresses regulares deve

ocorrer aos poucos. Aqui esto alguns exemplos. Lembre-se sempre de us-los entre barras /.../ [01] # tanto "0" ou "1" \/0 # diviso por zero \/ 0 # diviso por zero com um espao \/\s0 # diviso por zero com um espao em branco # "/ 0" onde o espao pode ser um tab, por exemplo \/ *0 # diviso por zero com nenhum ou alguns espaos # "/0" ou "/ 0" ou "/ 0" etc \/\s+0 # diviso por zero com alguns espaos em branco \/\s+0\.0* # como o anterior, mas com ponto decimal # e alguns zeros depois dele, ou no # "/ 0." ou "/ 0.0" ou "/ 0.000" etc # observe a barra invertida antes do ponto Exerccios Seu programa anterior contava linhas no-vazias. Altere ele de modo que conte somente linhas com: a letra x a string para a string para, sendo p maisculo ou minsculo a palavra para ou Para, use \b para detectar palavras limitadas com um espao em branco (newline, tab, etc) Em cada caso, o programa deve mostrar toda linha, mas somente as especficas devem ser numeradas. Tente usar a varivel $_ para evitar o uso do operador de comparao =~. Substituio e traduo Uma vez identificadas as expresses regulares, Perl permite fazer substituies baseadas naquelas comparaes. O modo de fazer isso usando a funo s que parecida com o modo de substituio usado pelo editor de texto vi do Unix. Mais uma vez o operador de comparao usado, e mais uma vez se ele for omitido ento a substituio utilizar a varivel $_ em seu lugar. Para substituir uma ocorrncia de londres por Londres na $sentena devemos usar a expresso: $sentenca =~ s/londres/Londres/ e para fazer o mesmo com a varivel $_ use: s/londres/Londres/ Note que as duas expresses regulares esto usando um total de trs barras. O resultado desta expresso o nmero de substituies feitas, de modo que pode ser tanto zero (falso) como um (verdadeiro), no caso acima. Opes Recordando modelos Traduo Exerccios Opes Este exemplo somente substitui a primeira ocorrncia da string, mas pode ser que tenha mais do que uma string que desejamos substituir. Para fazer uma substituio global, a ltima barra deve ser seguida por um g: s/londres/Londres/g que obviamente utiliza a varivel $_. Novamente a expresso retorna o nmero de substituies realizadas, que zero ou alguma coisa maior que zero (verdadeiro). Se desejarmos tambm substituir ocorrncias de lOndres, lonDRES, LoNDrES e assim por diante, ento podemos usar:

s/[Ll][Oo][Nn][Dd][Rr][Ee][Ss]/Londres/g mas um modo mais fcil usar a opo i (para ignorar letras maisculas ou minsculas). A expresso: s/londres/Londres/gi far uma substituio global no importando se foi usado letras maisculas ou minsculas. A opo i tambm pode ser usada em expresses regulares bsicas.

Recordando modelos frequentemente til recordar modelos que tem sido comparados de modo que eles possam ser usados novamente. Isto ocorre porque qualquer coisa comparada entre parnteses retorna nas variveis $1,...,$9. Estas strings tambm podem ser usadas da mesma forma que nas expresses regulares (ou substituies) utilizando os cdigos especiais ER \1,...,\9. Esse teste: $_ = "Lorde Whopper de Fibbing"; s/([A-Z])/:\1:/g; print "$_\n"; colocar cada letra maiscula entre : (dois pontos). Neste exemplo, mostrar :L:orde :W:hopper de :F:ibbing. As variveis $1,...,$9 so somente de leitura, voc no pode alter-las. Como outro exemplo, o teste: if (/(\b.+\b) \1/) { print "Encontrou $1 repetida\n"; } ir identificar qualquer palavra repetida. Cada \b representa uma palavra limitada e .+ compara qualquer string no vazia, ento \b.+\b compara qualquer coisa entre duas palavras limitadas. O resultado ento armazenado como \1 para expresses regulares e como $1 para o resto do programa. Se $_ for igual a "teste teste teste2 teste2", a mensagem ser mostrada, mas somente com a primeira ocorrncia. O seguinte exemplo troca o primeiro e ltimo caracteres da linha na varivel $_: s/^(.)(.*)(.)$/\3\2\1/ O ^ e o $ comparam o incio e o fim da linha. O cdigo \1 armazena o primeiro caractere, o \2 armazena cada string entre os dois e o ltimo caractere armazenado no cdigo \3. Ento aquela linha substituda com a troca entre \1 e \3. Aps uma comparao, voc pode usar variveis especiais somente de leitura $` ou $& ou $' para encontrar o que foi comparado antes, durante e depois da busca. Ento: $_ = "Lorde Whopper de Fibbing"; /pp/; resultar em verdadeiro nas seguintes declaraes (recorde que eq um teste usado em strings): $` eq "Lorde Who"; $& eq "pp"; $' eq "er de Fibbing"; Finalmente, sobre o tpico Recordando modelos, o importante saber que dentro de barras de uma comparao ou substituio, as variveis so interpoladas. Ento: $busca = "par"; s/$busca/xxx/g; ir substituir cada ocorrncia com xxx. Se voc quiser substituir cada ocorrncia de para ento voc no pode usar s/$buscaa/xxx/g porque o a ser interpolado com a varivel $busca. Ao invs disso, voc deve colocar o nome da varivel entre chaves, de modo que o cdigo seja: $busca = "par"; s/${busca}a/xxx/g;

Traduo A funo tr permite a traduo caractere-a-caractere. A seguinte expresso substitui cada a com e, cada b com d, cada c com f na varivel $sentena. A expresso retorna o nmero de substituies efetuadas: $sentenca =~ tr/abc/edf/ A maioria dos cdigos especiais ER no se aplica funo tr. Por exemplo, a prxima declarao conta o nmero de asteriscos na varivel $sentena e armazena na varivel $contagem: $contagem = ($sentenca =~ tr/*/*/); Contudo, o trao permanece como seu uso entre. Esta declarao converte toda $_ para letra maiscula: tr/a-z/A-Z/; Exerccios Seu ltimo programa contava linhas de um arquivo que continham uma certa string. Modifique ele de modo que conte linhas com letras duplas (ou qualquer outro caractere duplo). Modifique novamente para que estas letras duplas apaream entre parnteses. Por exemplo, seu programa deve produzir algo como: 023 E(ss)es pioneiros conduziram muitas se(ss)es Tente fazer com que todos os pares de letras sejam colocados entre parnteses, e no apenas o primeiro par de cada linha. Para um programa mais interessante, voc deve tentar o seguinte. Suponha que seu programa se chama contalinhas. Ento voc deve execut-lo com: perl contalinhas Contudo, se voc cham-lo com vrios argumentos, como em: perl contalinhas primeiro segundo etc ento estes argumentos sero armazenados em uma matriz @ARGV. No exemplo acima, ns teremos $ARGV[0] igual a primeiro, $ARGV[1] igual a segundo e $ARGV[2] igual a etc. Modifique seu programa de modo que ele aceite uma string como argumento e conte somente linhas com essa string. Ele deve tambm colocar ocorrncias dela entre parnteses. Ento: perl contalinhas par dever retornar algo como: 019 Mas (par)a os grandes pioneiros, suas (par)tes eram...

Split Uma funo muito til no Perl a split, que separa uma string e coloca em uma matriz. A funo usa expresses regulares e tambm funciona com a varivel especial $_. A funo split usada desta forma: $info = "Caine:Michael:Ator:Doce Liberdade"; @pessoal = split(/:/, $info); que tem o mesmo efeito que: @pessoal = ("Caine", "Michael", "Ator", "Doce Liberdade"); Se a informao estiver armazenada na varivel $_ ento poderemos usar somente: @pessoal = split(/:/); Se os campos so divididos por vrios dois pontos, ento podemos usar os cdigos ER para certos problemas. O cdigo: $_ = "Caine::Michael:::Ator"; @pessoal = split(/:+/); o mesmo que: @pessoal = ("Caine", "Michael", "Ator"); mas se no for usado, ento:

$_ = "Caine::Michael:::Ator"; @pessoal = split(/:/); ser o mesmo que: @pessoal = ("Caine", "", "Michael", "", "", "Ator"); Uma palavra pode ser separada em caracteres, uma sentena separada em palavras e um pargrafo em sentenas: @caracteres = split(//, $palavra); @palavras = split(/ /, $sentenca); @sentencas = split(/\./, $paragrafo); No primeiro caso, a string nula comparada entre cada caractere, e isso ocorre porque @caracteres uma matriz de caracteres, i., uma matriz de strings com comprimento 1. Exerccios Exerccios Uma ferramenta til no processamento de nossa lngua natural a concordncia. Este permite que uma string especfica seja mostrada em seu contexto imediato, em qualquer lugar que aparea no texto. Por exemplo, um programa de concordncia identificando a string destino par talvez possa produzir alguma das seguintes sadas. Note como as ocorrncias da string destino se alinham verticalmente: o primeiro par de ligaes ocorreu sendo que para entender os proble no segundo par existe a possibilid s o ltimo par deve conter a final Neste exerccio, voc deve fazer esse programa. Aqui esto algumas dicas: coloque o arquivo inteiro em uma matriz (geralmente isso no til porque o arquivo pode ser extremamente grande, mas no devemos nos preocupar com isso agora). Cada item na matriz ser uma linha do arquivo. quando a funo chop usada em uma matriz, ela elimina o ltimo caractere de cada item da matriz. recorde que voc pode juntar a matriz inteira com uma declarao como $texto = "@linhas"; use a string destino como delimitador para separar o texto (i., use a string no lugar dos dois pontos usados nos exemplos anteriores). Voc deve ento ter uma matriz de todas as strings entre cada string destino. para cada elemento da matriz, mostre ele, a string destino, e ento mostre o prximo elemento da matriz. recorde que o ltimo elemento de uma matriz @comida tem ndice $#comida. Este deveria ser um bom programa, mas a string destino no se alinhar verticalmente. Para alinhar essas strings, voc precisar da funo substr. Aqui esto trs exemplos de seu uso: substr("Era uma vez a...", 3, 4); # retorna " uma" substr("Era uma vez a...", 7); # retorna " vez a..." substr("Era uma vez a...", -6, 5); # retorna "z a.." O primeiro exemplo retorna uma substring de comprimento 4 comeando a partir da posio 3. Recorde que o primeiro caractere de uma string tem ndice zero. No segundo exemplo, se faltar o comprimento, toda a substring a partir da posio 7 mostrada. O terceiro exemplo mostra que voc tambm pode contar a partir do final, usando um ndice negativo. Ele retorna a substring que comea a partir do sexto caractere contado da direita para a esquerda com comprimento de 5 caracteres. Se voc usar um ndice negativo que estende alm do comeo da string, ento o Perl retornar nada ou uma mensagem de erro. Para evitar que isso ocorra, voc pode aumentar o tamanho da string usando o operador x, como mencionado antes. Por exemplo, a expresso (" "x30) produz 30 espaos. Matrizes associativas Uma lista comum de matriz permite acessar seus elementos atravs de nmeros. O primeiro elemento da matriz @comida $comida[0]. O segundo $comida[1], assim por diante, sendo que o ltimo elemento $comida[$#comida]. Mas o Perl tambm permite criar matrizes que so acessadas por uma string. Estas so chamadas de matrizes associativas. Para definir uma matriz associativa, usamos a notao usual com parnteses, mas a matriz agora prefixada por um sinal %. Suponha que ns queremos criar uma matriz de pessoas com suas idades. Ela pode ser algo como: %idades = ("Michael Caine", 39, "Den", 34, "Angie", 27,

"Willy", "21 anos de cachorro", "A rainha me", 108); Agora podemos encontrar a idade de cada pessoa com as seguintes expresses: $idade{"Michael Caine"}; # Retorna 39 $idade{"Den"}; # Retorna 34 $idade{"Angie"}; # Retorna 27 $idade{"Willy"}; # Retorna "21 anos de cachorro" $idade{"A rainha me"}; # Retorna 108 Note que como na matriz comum, cada sinal % foi alterado para um $ para acessar um elemento individual porque cada elemento escalar. Mas, de forma diferente da lista comum, onde o ndice colocado entre parnteses, a idia est em facilitar o acesso atravs da associao de cada par de elementos. Uma matriz associativa pode ser convertida em uma comum apenas atribuindo ela a uma varivel @, e vice-versa. Note porm que a converso no coloca os elementos pares em ordem, como veremos adiante; @info = %idades; # @info uma lista comum. Ela tem agora 10 elementos $info[5]; # retorna o valor 27 %maisidades = @info; # %maisidades tem agora 5 pares de elementos Operadores Variavis de Ambiente Operadores Matrizes associativas no ordenam seus elementos (elas so como grandes tabelas confusas) mas possvel acessar todos seus elementos usando funes de chaves e funes de valores: foreach $pessoa (keys %idades) { print "Eu sei a idade de $pessoa\n"; } foreach $idade (values %idades) { print "Algum tem $idade\n"; } Quando keys chamada, ela retorna uma lista de ndices da matriz associativa. Quando values chamada, ela retorna uma lista dos valores da matriz. Essas funes retornam suas listas na mesma ordem, mas esta ordem no tem nada a ver com a ordem em que os elementos foram inseridos. Quando keys e values so chamadas em um contexto escalar, elas retornam o nmero de pares na matriz associativa. Existe tambm um funo que retorna uma lista de dois elementos de uma chave e seu valor. Cada vez que chamada, ela retorna outro par de elementos: while (($pessoa, $idade) = each(%idades)) { print "$pessoa tem $idade\n"; } Variavis de Ambiente Quando voc roda um programa em Perl, ou qualquer script no Unix, certas variveis de ambientes so setadas. Algumas podem ser como $ENV{'USER'} que contm o username (nome do usurio logado). Quando voc roda um script CGI na WWW, existem variveis de ambiente que possuem outras informaes teis. Todas essas variveis e seus valores so armazenados na matriz associativa %ENV em que as chaves so os nomes das variveis. O seguinte exemplo retorna todas as suas variveis de ambiente: while (($chave, $valor) = each(%ENV)) { print "$chave igual a $valor\n"; }

Subrotinas Como qualquer linguagem estruturada, Perl permite ao usurio definir suas prprias funes, chamadas subrotinas. Elas podem ser colocadas em qualquer lugar do programa, mas o ideal coloclas no incio, ou tudo no final. Uma subrotina tem sempre o formato: sub subrotina { print "Esta uma rotina muito simples.\n"; print "Ela sempre faz a mesma coisa...\n"; } As seguintes declaraes servem para chamar a subrotina. Note que ela invocada com um caractere & na frente do nome: &subrotina; # chama a subrotina &subrotina($_); # chama ela com um parmetro &subrotina(1+2, $_); # chama com dois parmetros Parmetros Retornado Valores Variveis Locais Parmetros Nos casos acima, os parmetros so aceitos porm ignorados. Quando a subrotina chamada, os parmetros so passados como uma lista na varivel especial @_. Esta varivel no tem nada a ver com a varivel escalar $_. A seguinte subrotina simplesmente mostra a lista de argumentos passados: sub argumentos { print "@_\n"; } Alguns exemplos de seu uso: &argumentos("primeiro", "segundo"); # mostra primeiro segundo &argumentos("mas", "e", "uvas"); # mostra mas e uvas Como em qualquer outra matriz comum, os elementos individuais de @_ podem ser acessados com a notao entre colchetes: sub primeiros { print "Primeiro argumento: $_[0]\n"; print "Segundo argumento: $_[1]\n"; } Novamente importante recordar que as variveis escalares indexadas $_[0], $_[1], etc no tm nada a ver com a varivel $_, que pode ser usado normalmente sem causar problemas. Retornando valores O resultado de uma subrotina sempre a ltima coisa a se realizar. Esta subrotina retorna o maior valor: sub maior { if ($_[0] > $_[1]) { $_[0]; } else

{ $_[1]; } } Neste exemplo, $maior ser igual a 37: $maiorvalor = &maior(37, 24); A subrotina &primeiros tambm retorna um valor, que neste caso 1. Isto ocorre porque a ltima coisa que aconteceu foi a execuo da funo print, e quando essa declarao funciona corretamente, ela resulta em 1.

Variveis locais A varivel @_ local somente para a corrente subrotina, e assim so as demais, como $_[0], $_[1], etc. Outras variveis tambm podem ser locais, e isto til se quisermos comear alterando os parmetros passados. A seguinte subrotina verifica se uma string est dentro de outra, comparando sem os espaos entre as palavras: sub dentro { local($a, $b); # cria variveis locais ($a, $b) = ($_[0], $_[1]); # atribui valores $a =~ s/ //g; # retira espaos das $b =~ s/ //g; # variveis locais ($a =~ /$b/ || $b =~ /$a/); # $b est dentro de $a, # ou $b contm $a? } A seguinte expresso retorna verdadeiro: &dentro("mamo", "lima mo"); De fato, voc tambm pode eliminar redundncias substituindo as duas primeiras declaraes do bloco pela linha: local($a, $b) = ($_[0], $_[1]);

You might also like