Функцию простого копирования


Я собрал эту чрезвычайно простую функцию текста дифф некоторое время назад:

function diff($old, $new) {
    $old = trim($old);
    $new = trim($new);

    if($old == $new) {
        return $new;
    }

    $old    = explode(" ", $old);
    $new    = explode(" ", $new);           
    $result = "";       
    $length = max(count($old), count($new));

    for($i = 0; $i < $length; $i++) {
        if(!isset($new[$i])) {
            $result .= "<del>{$old[$i]}</del>";
            continue;
        }

        if(!isset($old[$i])) {
            $result .= "<ins>{$new[$i]}</ins> ";
            continue;
        }           

        if($old[$i] != $new[$i]) {
            $result .= "<del>{$old[$i]}</del><ins>{$new[$i]}</ins> ";
            continue;
        }

        $result .= "{$new[$i]} ";
    }

    $result = str_replace(array("</ins> <ins>", "</del> <del>"), " ", $result);     

    return trim($result);   
}

$string1 = "Hello World!! Please review my diff function. Be gentle.";
$string2 = "Hello world! Please critique my diff function. Be extra vigilant.";

echo diff($string1, $string2);
// Hello <del>World!!</del><ins>world!</ins> Please <del>review</del><ins>critique</ins> my diff function. Be <del>gentle.</del><ins>extra vigilant.</ins>

Вывода HTML:

Здравствуй Мир!!мира! Пожалуйста, комментарийкритика моя дифференциал функции. Быть нежной.дополнительную бдительность.

Назначение функции не было что-то важное, а я даже не помню, зачем я ее создал (нашел в своей песочнице каталог, где полно небольших экспериментов). Хорошо ли это? Я всегда использовал груша Text_Diff для текстовых различий, но если я не делаю ничего плохого в моем простая функция, я бы хотел использовать его вместо.

Любые предложения о простой способ, чтобы переместить HTML вне функции?



2290
3
php
задан 28 ноября 2011 в 11:11 Источник Поделиться
Комментарии
3 ответа

Он выглядит прекрасно. Несколько заметок:

1, использовать максимум вместо

$length = count($old) > count($new) ? count($old) : count($new);

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

3, http://en.wikipedia.org/wiki/Longest_common_subsequence может быть полезна, если вы хотите лучше алгоритм.

4, для удаления HTML-код функции создать класс, который это делает и делегировать вызовы к нему. Например:

public interface Decorator {

public function delete($input);

public function insert($input);

public function removeUnnecessaryMarkers($input);
}

public class HtmlDecorator {
public function delete($input) {
return "<del>{$input}</del>";
}
public function insert($input) {
return "<ins>{$input}</ins>";
}
public function removeUnnecessaryMarkers($input) {
return str_replace(array("</ins> <ins>", "</del> <del>"), " ", $input);
}
}

...
if(!isset($new[$i])) {
$result .= $decorator->delete($old[$i]);
continue;
}
...

(Я не проверял, что это допустимый синтаксис PHP или нет. Не стесняйтесь, чтобы исправить это.)

2
ответ дан 28 ноября 2011 в 01:11 Источник Поделиться

Выложили бы это в качестве комментария, но только сейчас зарегистрировался, чтобы добавить этот вход так и не получил, что privalige еще! Ты посмотрел в гугле-дифф-матч-патч библиотеки? Там могут быть некоторые хорошие алгоритмические идеи можно взять из этого? Нет пример на PHP, но у них есть несколько других вариантов в язык есть.

2
ответ дан 30 ноября 2011 в 10:11 Источник Поделиться

Похоже, программа может обрабатывать только замене, до конца.
Как если бы вы дали его

A B C D E
A C D E

было бы сказать, что б был заменен на С, С на D, D К Е, и Е удалил. Это четыре смены, а не только одно изменение, исключив Б.

Есть другой способ, где вы можете проработать детали.
Это два показателя, я и Джей.
Когда старый[я] == новый[Дж], как я и J не увеличивается.
В противном случае вы идете в поиск диагональ сравнивая элементы, такие как этот:

i+1, j+0
i+0, j+1

i+2, j+0
i+1, j+1
i+0, j+2

i+3, j+0
i+2, j+1
i+1, j+2
i+0, j+3

пока вы не получите матч. Тогда вы знаете, сколько элементов между ними были вставлены или удалены.

1
ответ дан 30 ноября 2011 в 02:11 Источник Поделиться