Bueno, he encontrado una solución.
Using perl Syntax Highlighting
#!/usr/bin/perl -l
@lineas = (
'1Pedro Perez 23232956',
'1Jaime Perez 28732956',
'1SergioPerez 26732956',
);
# Leemos los argumentos
my @pos;
for my $pos ( @ARGV ) {
my ($primera,$ultima) = split q{,}, $pos;
push @pos, $primera;
push @pos, $ultima+1; # Aquí está el primer truco
}
# Ordenación de las posiciones, en orden inverso
@pos = sort { $b <=> $a } @pos;
print "@pos";
# Para todas las líneas...
for my $linea ( @lineas ) {
my $pos_ant = 0; # Recordaremos la última posición
# Para todas las posiciones...
for my $pos ( @pos ) {
next if $pos == $pos_ant; # No la tenemos en cuenta si ya la pusimos antes
substr($linea,$pos,0) = '*'; # Colocamos el punto peludo
$pos_ant = $pos; # Recuerda...
}
print "$linea";
}
__OUT__
> ./separar
.pl 1
,6 7
,17
18 7 7 1
1*Pedro *Perez *23232956
1*Jaime *Perez *28732956
1*Sergio*Perez *26732956Coloreado en 0.002 segundos, usando
GeSHi 1.0.8.4
La estrategia es la siguiente:
1. Consideramos que todas las coordenadas que nos pasan están basadas en 0.
2. Las coordenadas que nos indican, separadas por una coma, van del carácter inicial al final del campo a separar. En una situación normal, usando el substr() como en los ejemplos anteriores, no hay problema en usar la coordenada inicial (pues está sobre el primer carácter del campo), pero sí en la coordenada final. No podemos colocar allí el asterisco, sino en la posición siguiente (el asterisco debe rodear el campo, colocándose delante del primer carácter del siguiente campo). Por eso le sumamos 1 en la coordenada final.
3. Ordenamos las coordenadas de forma numérica y al revés, para evitar los mismos problemas que comentamos en los primeros mensajes: es mejor que el string vaya creciendo desde el final hasta el principio para no tener que hacer cuentas de desplazamiento de coordenadas.
4. La única preocupación que queda a la hora de colocar los asteriscos es ver si vamos a colocar un asterisco dos veces en el mismo sitio. Por eso usamos una variable que nos recuerda la última posición puesta. Si es igual a la actual, pasamos a la siguiente.
De esta forma, incluso se tienen en cuenta otros casos extremos:
a. Coordenadas repetidas:
perl separar.pl 1,6 1,6
1*Pedro *Perez 23232956
b. Coordenadas desordenadas:
perl separar 7,17 1,6
1*Pedro *Perez *23232956
c. Coordenadas con rangos comunes:
perl separar 1,6 3,17
1*Pe*dro *Perez *23232956
Incluso substr es lo bastante inteligente como para poner un asterisco al final de la cadena, pero no más allá.