La idea es buena, pero hay una serie de cuestiones que no están bien resueltas...
- .length no existe en Perl. Quítalo
- La expresión regular que usas para buscar cadenas utiliza el cuantificador {2,}, con lo que estás indicando que la $subcadena se debe repetir, al menos dos veces, seguidas, y decías que el problema era encontrar las repeticiones a lo largo de la $linea.
- Podrías evitar el intercambio de valores en las variables $e e $i, si cada una de ellas tiene una misión clara
- gt es para comparaciones alfanuméricas. Necesitas usar '>' para hacer comparaciones numéricas
Esta es mi versión, basada en la tuya:
Using perl Syntax Highlighting
#!/usr/bin/perl
use strict;
use warnings;
use diagnostics;
my $linea = '12345ja12345jaxd12345jaxd1117';
my $aux;
my $aux_n = 0;
my @array = split //, $linea;
for my $e (0 .. $#array) { # $e recorre los índices de todo el @array
my $subcadena = "";
for (my $i = $e; $i < @array; $i++) { # recorremos el resto de letras de la línea
$subcadena .= $array[$i]; # subcadena a buscar
# print "[$subcadena]:";
my $pos = $e - 1; # damos un paso atrás, ya que luego sumamos 1
my $cnt = 0; # contador de apariciones
while ($pos < @array) { # usamos index para buscar,
$pos = index($linea, $subcadena, $pos+1); # a partir de la posición $pos+1
if ($pos != -1) { # la encontramos
$cnt++; # contamos una vez más
}
else { # no encontramos más,
last; # terminamos
}
}
# print "$cnt\n";
# Valor más alto: si ha habido más de una repetición y
# la longitud es mayor de la encontrada hasta ahora
if ( $cnt > 1 and length($subcadena) > length($aux) ) {
$aux = $subcadena;
$aux_n = $cnt;
}
}
}
print "[$aux][$aux_n]\n"; # informamos de la cadena y veces que aparece
__END__
[12345jaxd1][2]
Coloreado en 0.003 segundos, usando
GeSHi 1.0.8.4
Esta es otra versión, usando expresiones regulares, pero menos eficiente
Using perl Syntax Highlighting
#!/usr/bin/perl
use 5.010;
use strict;
use warnings;
use diagnostics;
my $linea = '12345ja12345jaxd12345jaxd1117';
#say $linea;
my $aux;
$linea =~ /
(.+) # buscamos una subcadena
.*? # que está separado por unas letras
\1 # de una copia de sí misma (vamos, otra repetición)
(?{ # entonces, ejecutamos
if (length($1) > length($aux)) { # si lo encontrado es mayor de lo que teníamos
$aux = $1; # lo guardamos
#say "[$aux]"; # y pintamos (opcional)
}
})
(*FAIL) # repite la búsqueda por toda la cadena
/x;
say $aux; # pintamos la subcadena encontrada
__END__
12345jaxd
Coloreado en 0.001 segundos, usando
GeSHi 1.0.8.4
P.D. Como curiosidad, en la cadena de búsqueda, hay otra subcadena de la misma longitud que la encontrada antes:
2345jaxd1. Para encontrar ésta última, basta con cambiar los '>' por '>='.