2014-11-20 9 views
4

Я пытаюсь выяснить, какие символы пользователь изменил в строке. Я, к счастью, могу предположить, что есть только один, последующий блок изменений.Вычислить разницу строк как диапазон

Я даже не смог найти, где начинается измененная область:

var originalVal, val; //strings 
//The ranges 
var original = [0,0]; 
var new_rang = [0,0]; 
//Old length, new length 
var ol = originalVal.length; 
var nl = val.length; 
//Find where the change begins (that should be the same for both arrays) 

for(var i=0; ; i++) { 
    //If end of string was reached or the strings are different 
    if((i>=ol||i>=nl) || originalVal[i]!=val[i]) { 
    original[0] = new_rang[0] = i; 
    //Set these to i too, assuming there was no change 
    original[1] = new_rang[1] = i; 
    break; 
    } 
} 

Это полностью ломает, если есть ряд одинаковых символов и пользователь удаляет один в середине:

mmmmx
м м MMX
ттт х

Сценарий скажет, что изменение произошло на 4, где переместился x. Но на самом деле даже не представляется возможным сказать , которыйm был удален.

Я могу, однако, указать, где позиция курсора была в начале и где она находится в конце. Таким образом, это выглядит более перспективным, но до сих пор не знаю, что делать:

мм | MMX
м м | MMX
м | MMX

На этот раз я могу см., который m был удален. Но я до сих пор не знаю, как объяснить это на компьютере.

+0

Использование библиотеки, такие как https://code.google.com/p/google-diff-match-patch/wiki/API. Или http://ejohn.org/files/jsdiff.js. См. Также http://stackoverflow.com/questions/4595108/comparing-two-strings-or-objects-and-getting-the-difference-back/4595225#4595225. –

+0

Могу я просто спросить, есть ли какая-то особая цель узнать, кто был удален? Если вы собираетесь отменить действие, не имеет значения, если 'm' был вставлен в конце' m ', пользователю он выглядит одинаково, правильно? Так почему же вам нужно это знать? – somethinghere

+0

Я реализовал пользовательский скрипт для переполнения стека, который позволяет мне вставлять изображения по тексту. Этот пользовательский текст не блокирует ваше письмо - вы можете ввести его после вставки изображения и когда URL-адрес загружен, он будет заменен. В этом случае часто возникает вопрос об изменениях - или, по крайней мере, это то, что я помню. Кроме того, я пытался создать довольно общее решение, применимое к другим проектам. Вот сценарий: http://stackapps.com/questions/4999/stackpaste-paste-images-into-the-text-form-instantly –

ответ

1

Вот что я думаю, что вы, возможно, ищете. Пожалуйста, уточните свой вопрос.

var Console = function() { 
 
    this.log = function(msg) { 
 
    debug(msg) 
 
    }; 
 
}; 
 
var console = new Console(); 
 

 
function diffLengths(longer, shorter) { 
 
    var indexes = []; 
 
    var isTheSame = true; 
 
    for (var i = 0; i < shorter.length; i++) { 
 
    if (shorter[i] != longer[i]) { 
 
     isTheSame = false; 
 
     indexes.push(i); 
 
    } 
 
    }; 
 
    if (isTheSame) { 
 
    // The shorter string is exactly the same as the longer string 
 
    // except for the extra characters in the longer string 
 
    indexes.push(shorter.length); 
 
    } 
 
    return indexes; 
 
} 
 

 
function getDiffRange(first_string, second_string) { 
 
    var indexes = []; 
 
    if (first_string.length > second_string.length) { 
 
    return diffLengths(first_string, second_string); 
 
    } else if (first_string.length < second_string.length) { 
 
    return diffLengths(second_string, first_string); 
 
    } else { 
 
    for (var i = 0; i < first_string.length; i++) { 
 
     if (second_string[i] != first_string[i]) { 
 
     indexes.push(i); 
 
     } 
 
    }; 
 
    } 
 
    return indexes; 
 
} 
 

 
var range = getDiffRange('mmmmx', 'mmmx'); 
 
document.getElementById('result-1').innerHTML = range[0] + " - " + range[range.length - 1]; 
 

 
var range = getDiffRange('mmmmx', 'mmmxc'); 
 
document.getElementById('result-2').innerHTML = range[0] + " - " + range[range.length - 1]; 
 

 
var range = getDiffRange('mm', 'mmx'); 
 
document.getElementById('result-3').innerHTML = range[0] + " - " + range[range.length - 1];
table, th, td { 
 
\t border-collapse: collapse; 
 
\t border: 1px solid #ddd; 
 
\t text-align: left; 
 
\t padding: 7px; 
 
}
<html> 
 

 
<body> 
 
    <table> 
 
    <tr> 
 
     <th>input</th> 
 
     <th>result</th> 
 
    </tr> 
 
    <tr> 
 
     <td>'mmmmx', 'mmmx':</td> 
 
     <td id='result-1'></td> 
 
    </tr> 
 
    <tr> 
 
     <td>'mmmmx','mmmxc':</td> 
 
     <td id='result-2'></td> 
 
    </tr> 
 
    <tr> 
 
     <td>'mm','mmx':</td> 
 
     <td id='result-3'></td> 
 
    </tr> 
 
    </table> 
 
</body> 
 

 
</html>

+0

Спасибо за ваш ответ. Честно говоря, я уже решил проблему более года назад, поскольку мне это нужно, чтобы [освободить этот пользовательский текст] (http://stackapps.com/q/4999/28478). Но в любом случае, что число возвращаемых значений от вашей функции означает? –

+0

Прохладный. Можете ли вы опубликовать свой ответ и принять, какой ответ лучше. Чтобы поставить этот вопрос в закрытое состояние. Массивы 'indexes', которые возвращаются, представляют собой набор индексов, в которых две строки различаются – sdc

+0

Я согласен с этим. Мне просто не хочется врываться в мой код в ближайшее время. Я написал этот сценарий в течение 2 ночей, и все получилось. –

Смежные вопросы