Laboratorio: Comparar textos mediante Javascript
Hace unos días hablábamos de cómo comparar imágenes mediante PHP, y hoy, debido a una pregunta de un lector de Sentido Web, vamos a explicar cómo comparar un texto mediante Javascript.
El proceso es el siguiente: obtenemos dos arrays con cada una de las líneas de los textos, la comparación de textos se va a realizar línea a línea, el primer texto sobre el segundo.
Tendremos dos punteros para recorrer ambos textos, se mostrarán los textos en bloques, diferenciando las partes distintas en cada texto.
Si las líneas son iguales no se hace nada, solo se muestran en bloque. Si son distintas comprobamos si la línea del primer texto está en el segundo texto, si no está es que la línea actual ha sido modificado o insertada en el primer texto, si se encuentra, entonces es que la línea en el segundo texto ha sido insertada. En el primer caso incrementamos el puntero del primer texto únicamente y se marca como modificación en el primer texto, igualmente para el segundo texto cuando no se cumple la condición anterior. Finalmente se muestra el texto auxiliar si no se ha podido mostrar anteriormente y las líneas de texto que no se han mostrado del primero y segundo texto.
function compara() {
// Obtenemos las lineas de los textos
var txt1 = document.getElementById("txt1").value.split("\n");
var txt2 = document.getElementById("txt2").value.split("\n");
var html = "";
var aux = "";
var cont1 = 0;
var cont2 = 0;
var pos = -1;
var estado = 0; // 0 = ambos; 1 = texto 1; 2 = texto 2
// Vamos recorriendo ambos textos
while (cont1 < txt1.length && cont2 < txt2.length) {
if (txt1[cont1] == txt2[cont2]) {
// Si son iguales
// Si hay texto previo distinto al tipo actual lo mostramos
if (estado != 0) {
html += '<span class="cod'+estado+'">'+aux+'</span>';
aux = "";
}
// Escribimos el texto en una variable auxiliar
// Para mostrarlo por bloques
aux += txt1[cont1]+"\n";
// Aumentamos el puntero de los textos
cont1++;
cont2++;
// Marcamos como líneas iguales
estado = 0;
} else {
// Busco si la linea1 está en texto2
// si no está es que se trata de una linea modificada o insertada
var ok = false;
pos = -1;
// Comprobamos si la línea está en el otro texto
for (var i=cont2; i<txt2.length; i++) {
ok = ok || (txt1[cont1] == txt2[i]);
if (ok && pos >= 0) {
pos = i;
}
}
if (!ok) {
// Texto modificado o insertado
// Si hay texto previo distinto al tipo actual lo mostramos
if (estado != 1) {
html += '<span class="cod'+estado+'">'+aux+'</span>';
aux = "";
}
estado = 1;
aux += txt1[cont1++]+"\n";
} else {
// Texto insertado en el segundo texto
// Si hay texto previo distinto al tipo actual lo mostramos
if (estado != 2) {
html += '<span class="cod'+estado+'">'+aux+'</span>';
aux = "";
}
estado = 2;
aux += txt2[cont2++]+"\n";
}
}
}
// Si hay texto auxiliar no mostrado lo mostramos
if (aux!="") {
html += '<span class="cod0">'+aux+'</span>';
}
// Si sobre texto en el segundo texto lo mostramos
if (cont2 < txt2.length) {
aux = '<span class="cod2">';
for (var i=cont2; i<txt2.length; i++) {
aux += txt2[i]+"\n";
}
aux += "</span>";
html += aux;
}
// Si sobre texto en el segundo texto lo mostramos
if (cont1 < txt1.length-1) {
aux = '<span class="cod1">';
for (var i=cont1; i<txt1.length; i++) {
aux += txt1[i]+"\n";
}
aux += "</span>";
html += aux;
}
// Modificamos el contenedor del resultado
document.getElementById("dif").innerHTML = html;
}