 
 
 
 
 
 
 
 
 
 










 
$text proveniente
de un fichero CSV (Comma Separated Values). Esto es
el fichero contiene líneas con el formato:
"earth",1,"moon",9.374
Esta línea representa cinco campos.
Es razonable querer guardar esta información en un array,
digamos @field, de manera que $field[0] == 'earth',
$field[1] == '1', etc.
Esto no sólo implica descomponer la cadena en campos sino
también quitar las comillas de los campos entrecomillados.
La primera solución que se nos ocurre es hacer uso de la
función split:
@fields = split(/,/,$text);
Pero esta solución deja las comillas dobles en  los campos
entrecomillados.  Peor aún, los campos entrecomillados pueden contener
comas, en cuyo caso  la división proporcionada por split sería
errónea. 
   1 #!/usr/bin/perl -w
   2 use Text::ParseWords;
   3 
   4 sub parse_csv {
   5   my $text = shift;
   6   my @fields = (); # initialize @fields to be empty
   7 
   8   while ($text =~ 
   9     m/"(([^"\\]|\\.)*)",? # quoted fields
  10       | 
  11       ([^,]+),?           # $3 = non quoted fields
  12       | 
  13       ,                   # allows empty fields
  14     /gx 
  15     )
  16   {
  17     push(@fields, defined($1)? $1:$3); # add the just matched field
  18   }
  19   push(@fields, undef) if $text =~ m/,$/; #account for an empty last field
  20   return @fields;
  21 }
  22        
  23 $test = '"earth",1,"a1, a2","moon",9.374';
  24 print "string = \'$test\'\n";
  25 print "Using parse_csv\n:";
  26 @fields = parse_csv($test);
  27 foreach $i (@fields) {
  28   print "$i\n";
  29 }
  30 
  31 print "Using Text::ParseWords\n:";
  32 #  @words = "ewords($delim, $keep, @lines);  
  33 #The $keep argument is a boolean flag.  If true, then the
  34 #tokens are split on the specified delimiter, but all other
  35 #characters (quotes, backslashes, etc.) are kept in the
  36 #tokens.  If $keep is false then the &*quotewords()
  37 #functions remove all quotes and backslashes that are not
  38 #themselves backslash-escaped or inside of single quotes
  39 #(i.e., "ewords() tries to interpret these characters
  40 #just like the Bourne shell). 
  41 
  42 @fields = quotewords(',',0,$test);
  43 foreach $i (@fields) {
  44   print "$i\n";
  45 }
Las subrutinas  en Perl reciben sus argumentos en el array
@_. Si la lista de argumentos contiene listas, estas 
son ``aplanadas'' en una única lista. Si, como es el caso, la subrutina
ha sido declarada antes de la llamada, los argumentos pueden
escribirse sin paréntesis que les rodeen:
@fields = parse_csv $test;
Otro modo de llamar una subrutina es usando el prefijo &,
pero sin proporcionar lista de argumentos.
@fields = &parse_csv;En este caso se le pasa a la rutina el valor actual del array
@_.
Los operadores push (usado en la línea 17) y pop trabajan
sobre el final del array. De manera análoga los operadores
shift y unshift lo hacen sobre el comienzo.
El operador ternario ? trabaja de manera análoga como lo hace en C.
El código del push podría sustituirse por este otro:
push(@fields, $+);Puesto que la variable
$+ contiene la cadena que ha casado
con el último paréntesis que haya casado en el ultimo ``matching''.
La segunda parte del código muestra que existe un 
módulo en Perl, el módulo Text::Parsewords que proporciona la rutina quotewords que hace la misma función que nuestra subrutina.
Sigue un ejemplo de ejecución:
> csv.pl string = '"earth",1,"a1, a2","moon",9.374' Using parse_csv :earth 1 a1, a2 moon 9.374 Using Text::ParseWords :earth 1 a1, a2 moon 9.374
 
 
 
 
 
 
 
 
 
 










