Сравнить текст и получить различия
Ну, я хочу сравнить 2 строки (первая и вторая версии) и получить различия в формате, который я могу конвертировать в html самостоятельно, например, вы можете посмотреть, как пост был отредактирован здесь припереполнении стека или как svn отслеживает различия между изменения....
Это должна быть библиотека полного управляемого кода.
Как этот JavaScript, но мне нужно сделать это на стороне сервера..
2 ответа
У меня есть библиотека классов, которая делает это, я опубликую ссылку ниже, но я также опубликую, как она выполняет свою работу, чтобы вы могли оценить, будет ли она соответствовать вашему контенту.
Обратите внимание, что для всего, что я говорю ниже, если вы думаете о каждом символе как о элементе коллекции, вы можете реализовать алгоритм, описанный ниже, для любого типа контента. Будь то символы строки, строки текста, коллекции ORM-объектов.
Весь алгоритм вращается вокруг самой длинной подстроки (LCS) и является рекурсивным подходом.
Сначала алгоритм пытается найти LCS между двумя. Это будет самый длинный раздел, который не изменился / идентичен между двумя версиями. Затем алгоритм считает эти две части "выровненными".
Например, вот как две строки примера будут выровнены:
This long text has some text in the middle that will be found by LCS
This extra long text has some text in the middle that should be found by LCS
^-------- longest common substring --------^
Затем он рекурсивно применяется к частям перед выровненным участком, а затем к частям.
Окончательный "результат" может выглядеть следующим образом (я использую подчеркивание, чтобы указать части "не там" в одной из строк):
This ______long text has some text in the middle that ______will be found by LCS
This extra long text has some text in the middle that should____ be found by LCS
Затем, как часть рекурсивного подхода, каждый уровень рекурсивного вызова будет возвращать коллекцию "операций", которые в зависимости от того, есть ли LCS или отсутствующие части в любой части, будут выплевываться следующим образом:
- Если LCS, то это операция копирования
- Если отсутствует сначала, то это операция вставки
- Если отсутствует из второго, то это операция "удаления"
Таким образом, приведенный выше текст будет:
- Скопировать 5 символов (
This
) - Вставить
extra_
(очевидно, кодовые блоки здесь удаляют пробел, подчеркивание - пробел) - Скопировать 43 символа (
long text has some text in the middle that_
) - Вставить
should
- Удалить 4 символа (
will
) - Скопировать 16 символов (
_be found by LCS
)
Суть алгоритма довольно проста, и с помощью приведенного выше текста вы сможете реализовать его самостоятельно, если хотите.
В моей библиотеке классов есть некоторые дополнительные функции, в частности, для обработки таких вещей, как содержимое, похожее на измененный текст, так что вы не просто получаете операции удаления или вставки, но также изменяете операции, это в основном будет важно, если вы сравниваете список чего-то, например строки из текстовых файлов.
Библиотеку классов можно найти здесь: DiffLib на CodePlex, и вы также найдете ее на Nuget для простой установки в Visual Studio 2010. Она написана на C# для.NET 3.5 и выше, поэтому она будет работать для.NET 3.5 и 4.0 и, поскольку это бинарный выпуск (хотя весь исходный код находится на CodePlex), вы также можете использовать его из VB.NET.
У Google есть нечто похожее, и оно доступно в C#, но мы не стали рассматривать его более подробно. Демо выглядит довольно круто, хотя.