Creo que he conseguido encontrar una solución (no ha sido nada fácil).
Using perl Syntax Highlighting
#!/usr/bin/perl
use strict;
use warnings;
use utf8;
use open qw(:utf8 :std);
while (my $linea1 = <DATA> ) { # leemos línea a línea desde __DATA__
chomp $linea1;
my $linea2 = <DATA>; # leemos la segunda línea, también
chomp $linea2;
print "1:[$linea1]\n";
print "2:[$linea2]\n";
while ($linea1 =~ m/\G.*?(\w+)(?:\(([-\w]+)\))?/g) { # buscamos una palabra más código opcional
my($palabra, $codigo) = ($1, $2);
my $palabra2;
if ($linea2 =~ m/\G.*?(\w+)/g) { # recorremos segunda línea,
$palabra2 = $1; # buscando la siguiente palabra
if ($codigo and $palabra eq $palabra2) { # si teníamos un código y las palabras coinciden
my $anterior = pos $linea2; # guardamos la posición de la palabra
substr($linea2, $anterior, 0, "($codigo)"); # metemos con calzador el código, en ese lugar
pos($linea2) = $anterior + 2 + length $codigo; # posición para la siguiente búsqueda
}
}
}
print "3:[$linea2]\n";
print '-' x 60, "\n";
}
__DATA__
El(A) día(S) comenzó(V) con(P) viento(S-CCM) y(C) lluvia(S-CCM) en(P) Madrid(S-CCL).
El día había comenzado bien, con lluvia en Madrid.
El(A) día(S) comenzó(V) con(P) viento(S-CCM) y(C) lluvia(S-CCM) en(P) Madrid(S-CCL).
El comenzó el día bien, con lluvia y viento en Madrid.
La(A) jornada(S) se presentaba(V) ideal(A-CCM) para(P) salir(V) a(P) buscar(V) setas(S-OD).
La jornada pintaba muy bien para salir al campo.
La(A) jornada se presentaba(V) ideal(A-CCM) para(P) salir(V) a(P) buscar(V) setas(S-OD).
La jornada pintaba muy bien para salir al campo.
Coloreado en 0.004 segundos, usando
GeSHi 1.0.8.4
sale
Using text Syntax Highlighting
1:[El(A) día(S) comenzó(V) con(P) viento(S-CCM) y(C) lluvia(S-CCM) en(P) Madrid(S-CCL).]
2:[ El día había comenzado bien, con lluvia en Madrid.]
3:[ El(A) día(S) había comenzado bien, con lluvia(S-CCM) en(P) Madrid(S-CCL).]
------------------------------------------------------------
1:[El(A) día(S) comenzó(V) con(P) viento(S-CCM) y(C) lluvia(S-CCM) en(P) Madrid(S-CCL).]
2:[ El comenzó el día bien, con lluvia y viento en Madrid.]
3:[ El(A) comenzó el día bien, con lluvia(S-CCM) y viento en Madrid.]
------------------------------------------------------------
1:[La(A) jornada(S) se presentaba(V) ideal(A-CCM) para(P) salir(V) a(P) buscar(V) setas(S-OD).]
2:[ La jornada pintaba muy bien para salir al campo.]
3:[ La(A) jornada(S) pintaba muy bien para(P) salir(V) al campo.]
------------------------------------------------------------
1:[La(A) jornada se presentaba(V) ideal(A-CCM) para(P) salir(V) a(P) buscar(V) setas(S-OD).]
2:[ La jornada pintaba muy bien para salir al campo.]
3:[ La(A) jornada pintaba muy bien para(P) salir(V) al campo.]
------------------------------------------------------------
Coloreado en 0.000 segundos, usando
GeSHi 1.0.8.4
Un poco de explicación.
Usamos un while() para recorrer las palabras de la primera línea, y un if() para las de la segunda línea. Con el uso de
/g podemos hacer esas búsquedas repetidas. Observar (importante) que las dos expresiones regulares están en contexto escalar, por lo que lo que devuelven es un valor booleano (verdadero o falso) sobre si han encontrado la siguiente palabra o no.
Y como extraemos una palabra cada vez, de las dos líneas, estamos seguros de que se cumple la condición de que las palabras deben coincidir en posición.
Si, la primera línea, tenía un código, y las dos palabras son iguales, entonces hacemos la operación de modificación de la segunda línea. En el ejemplo indicado usamos substr(). Pero hay un problema: al usar substr(), las expr. reg. "olvidan" la posición de búsqueda, por lo que se "reiniciaría" la búsqueda de la siguiente palabra desde el comienzo, y no desde el final de la anterior búsqueda. Por eso usamos pos() para almacenar temporalmente esa posición. Después de hacer la inserción del código, ajustamos la posición a la que tenía antes, más lo que ocupa ahora el código.
La línea
Using perl Syntax Highlighting
substr($linea2, $anterior, 0, "($codigo)");
Coloreado en 0.001 segundos, usando
GeSHi 1.0.8.4
también se puede escribir como
Using perl Syntax Highlighting
substr($linea2, $anterior, 0) = "($codigo)";
Coloreado en 0.001 segundos, usando
GeSHi 1.0.8.4
Explicación de las expresiones regulares:
$linea1 =~ m/\G.*?(\w+)(?:\(([-\w]+)\))?/gDe forma repetida (
/g), buscamos en
$linea1, desde la última posición anterior (
\G), cero o más caracteres (
.*?) seguidos por una palabra (
\w+), que capturaremos, y seguido, opcionalmente seguidas por un par de paréntesis con un código dentro (
(?:\(([-\w]+)\))?), de que capturaremos el texto del código.
$linea2 =~ m/\G.*?(\w+)/gTambién, de forma repetida (
/g), buscamos en
$linea2, desde la última posición anterior (
\G), cero o más caracteres (
.*?) seguidos por una palabra (
\w+), que capturaremos.
Los comodines (
.*?) son necesarios para saltar los caracteres espacio y de puntuación.
Otra forma de hacer la inserción del código es por medio de una sustitución, pero es algo más lenta (cambiar las líneas 23 a 25 a éstas):
Using perl Syntax Highlighting
my $anterior = pos $linea2; # guardamos posición donde la encontramos
pos($linea2) -= length $palabra2; # retrocedemos a donde comienza la palabra
$linea2 =~ s/\G.*?\w+\K/($codigo)/; # y le agregamos el código
pos($linea2) = $anterior + 2 + length $codigo; # reposicionamos para la siguiente búsqueda
Coloreado en 0.001 segundos, usando
GeSHi 1.0.8.4