Back-End

27 nov, 2009

Funções split e join em Perl

Publicidade

A linguagem de programação Perl é rica em funções utilitárias, que permitem trabalhar com os dados de forma rápida e eficiente. Duas que merecem especial destaque serão o objetivo deste artigo:

  •  split: quebra uma cadeia de caracteres segundo um padrão
  •  join: junta elementos usando algum separador

Conhecer o uso e o funcionamento de cada uma delas pode tornar o código mais eficiente, menos propenso a erros e facilitar a vida como um todo, pois muitos problemas de programação acabam se relacionando a elas. Imagine, por exemplo, um arquivo de exportação
de dados tipo CSV (Comma-Separated-Value), que são aqueles arquivos que
podem ser usados para transferir as informações de uma planilha de dados do
Microsoft Excel ou Open Office Calc, sendo os valores delimitados por
algum separador, como o ponto-e-vírgula. O formato normal dele é:

Nome;Idade;Telefone
Jose;30;123
Maria;25;456
Joao;18;789

Repare que, em geral, ele não tem formatação, sendo que a primeira linha normalmente define o cabeçalho das informações e, da segunda linha em diante, ficam os valores propriamente ditos. Cada linha representa uma informação, bem próximo do que pode ser visto num banco de dados. O padrão de formação é existir um item de separação entre os valores. Relacionando isso ao uso da função split, fica evidente que uma maneira fácil de trazer esses dados para memória é processar cada uma das linhas individualmente e, depois, para cada uma delas, quebrá-las usando o ; (ponto e vírgula) como separador e fazer algum processamento:

# Abre o arquivo dados.csv para leitura
open (ARQUIVO, "</home/usuario/dados.csv");
my %estrutura = ();
my $indice = 0;
while ($linha = <ARQUIVO>) {
# desconsidera a primeira linha, de cabecalho

if ($indice == 0) {
++$indice;
next;
}
# remove o ultimo caracter da linha, no caso um "enter"

chop($linha);
my @dados = split(";", $linha);
$estrutura{$indice}{"nome"} = $dados[0];
  $estrutura{$indice}{"idade"} = $dados[1];
$estrutura{$indice}{"telefone"} = $dados[2];
++$indice;

}
# Fecha a referência para dados.csv
close ARQUIVO;

Uma referência para o arquivo a ser tratado é aberta e algumas estruturas de dados auxiliares são inicializadas. Em seguida, para cada linha do arquivo, primeiro é feito o teste de primeira linha e caso seja (não estamos interessados no cabeçalho), ela é desconsiderada. Para todas as demais iterações, o valor armazenado em $linha é quebrado tomando como base o separador e é retornado um vetor com os pedaços dela. Esse vetor é posteriormente colocado num hash para facilidade de manuseio.

A função join, por sua vez, faz o inverso de split, juntando pedaços de dados (que estiverem num vetor ou hash, por exemplo) e os retorna como uma string única. Essa função é muito usada desde a exibição de dados no resultado de um browser até na depuração de dados, tornando mais rápido a construção do código.

foreach my $idx (keys %estrutura) {

  my @juncao = values %{$estrutura{$idx}};
print join("|", @juncao) ."\n";

}

No exemplo continuado, pega-se a estrutura preenchida com os dados do arquivo e itera-se sobre eles. Para cada chave da estrutura (que é valor inteiro começando em 1), recupera-se os valores da chave corrente usando uma referência para o hash do segundo nível e fazendo uso da função values, que retorna os valores de hash (antes, para iterar sobre as chaves de um hash, foi usada a função keys, que retorna todas as chaves do hash). Por fim, usando o vetor gerado como parâmetro de entrada, a função join concatena cada um dos elementos do vetor usando o símbolo | e com a função print, exibe os dados na tela.

O código acima pode ser resumido um pouco mais, ao unir as duas linha do corpo da repetição:

foreach my $idx (keys %estrutura) {
print join("|", values %{$estrutura{$idx}}) ."\n";
}

Espero
que tenha sido exemplificado o grande poder e as possibilidades ao se
usar as duas funções, especialmente no processamento de cadeias de
caracteres que possuam alguma estrutura ou regra de formação. Um tópico
que merece um artigo futuro é a parte que trata da chamada de um hash 
dentro de um hash a partir de uma referência, então aguardem notícias.