[:,\t]
) que se repite mas veces en la
línea. Por ejemplo, la línea:
a:1,b:2,c:3,dse separará por comas produciendo la lista
["a:1", "b:2","c:3","d"]
,
pero la línea
a:1,b:2,c:3:dse separará mediante el carácter dos puntos produciendo la lista
["a","1,b", "2,c","3","d"]
.
Para resolver el problema se declaran dos variables max
y $maxcount
locales
al método asociado con la variable sintáctica line
que reconoce la
categoría gramatical línea. Para declarar tales variables
se usa la directiva rulevar
.
La otra directiva que se usa es reject
, la cuál hace
que la producción falle (exactamente igual que si la acción
hubiese retornado undef
). La estrategia consiste
en almacenar en, separador por separador llevar en $maxcount
el máximo número de items en que se descompone la línea
y en $max
la referencia al array anónimo ``ganador''.
#!/usr/local/bin/perl5.8.0 -w use strict; use Parse::RecDescent; use Data::Dumper; #$::RD_TRACE = 1; my $grammar = q{ line : <rulevar: $max> line : <rulevar: $maxcount = 0> line : <leftop: value ',' value> { $maxcount = @{$item[1]}; $max = $item[1]; print "maxcount[,] = $maxcount\n"; } <reject> | <leftop: datum ':' datum> { if (@{$item[1]} > $maxcount) { $maxcount = @{$item[1]}; $max = $item[1]; } print "maxcount[,:] = $maxcount\n"; } <reject> | <leftop: field ";" field> { if (@{$item[1]} > $maxcount) { $maxcount = @{$item[1]}; $max = $item[1]; } print "maxcount[,:;] = $maxcount\n"; } <reject> | { $return = $max; } value: /[^,]*/ datum: /[^:]*/ field: /[^;]*/ }; my $parse = Parse::RecDescent->new($grammar); my $line; while ($line = <>) { print "$line\n"; my $result = $parse->line($line); if (defined($result)) { print Dumper($result); } else { print "Cadena no válida\n"; } }Probemos el código con el siguiente fichero de entrada:
cat file3.txt 1:2:3,3:4;44 1,2:3,3:4;44 1;2:3;3:4;44He aqui una ejecución:
$ ./maxseparator.pl file3.txt 1:2:3,3:4;44 maxcount[,] = 2 maxcount[,:] = 4 maxcount[,:;] = 4 $VAR1 = [ '1', '2', '3,3', '4;44 ' ]; 1,2:3,3:4;44 maxcount[,] = 3 maxcount[,:] = 3 maxcount[,:;] = 3 $VAR1 = [ '1', '2:3', '3:4;44 ' ]; 1;2:3;3:4;44 maxcount[,] = 1 maxcount[,:] = 3 maxcount[,:;] = 4 $VAR1 = [ '1', '2:3', '3:4', '44 ' ];