Apa cara termudah untuk menyoroti perbedaan antara dua string di PHP?
Saya berpikir di sepanjang baris halaman riwayat edit Stack Overflow, di mana teks baru berwarna hijau dan teks yang dihapus berwarna merah. Jika ada fungsi atau kelas yang tersedia sebelumnya, itu akan ideal.
Baru saja menulis kelas untuk menghitung jumlah pengeditan terkecil (tidak secara harfiah) untuk mengubah satu string menjadi string lain:
http://www.raymondhill.net/finediff/
Ini memiliki fungsi statis untuk membuat versi HTML dari diff.
Ini adalah versi pertama, dan kemungkinan akan ditingkatkan, tetapi berfungsi dengan baik seperti sekarang, jadi saya membuangnya jika seseorang perlu menghasilkan diff kompak secara efisien, seperti yang saya butuhkan.
Edit: Sekarang ada di Github: https://github.com/gorhill/PHP-FineDiff
sumber
Ini bagus, juga http://paulbutler.org/archives/a-simple-diff-algorithm-in-php/
sumber
if($matrix[$oindex][$nindex] > $maxlen){
Undefined variable: maxlen
Jika Anda menginginkan pustaka yang kuat, Text_Diff (paket PEAR) tampaknya cukup bagus. Ini memiliki beberapa fitur yang cukup keren.
sumber
Berikut adalah fungsi singkat yang dapat Anda gunakan untuk membedakan dua larik. Ini mengimplementasikan algoritma LCS :
function computeDiff($from, $to) { $diffValues = array(); $diffMask = array(); $dm = array(); $n1 = count($from); $n2 = count($to); for ($j = -1; $j < $n2; $j++) $dm[-1][$j] = 0; for ($i = -1; $i < $n1; $i++) $dm[$i][-1] = 0; for ($i = 0; $i < $n1; $i++) { for ($j = 0; $j < $n2; $j++) { if ($from[$i] == $to[$j]) { $ad = $dm[$i - 1][$j - 1]; $dm[$i][$j] = $ad + 1; } else { $a1 = $dm[$i - 1][$j]; $a2 = $dm[$i][$j - 1]; $dm[$i][$j] = max($a1, $a2); } } } $i = $n1 - 1; $j = $n2 - 1; while (($i > -1) || ($j > -1)) { if ($j > -1) { if ($dm[$i][$j - 1] == $dm[$i][$j]) { $diffValues[] = $to[$j]; $diffMask[] = 1; $j--; continue; } } if ($i > -1) { if ($dm[$i - 1][$j] == $dm[$i][$j]) { $diffValues[] = $from[$i]; $diffMask[] = -1; $i--; continue; } } { $diffValues[] = $from[$i]; $diffMask[] = 0; $i--; $j--; } } $diffValues = array_reverse($diffValues); $diffMask = array_reverse($diffMask); return array('values' => $diffValues, 'mask' => $diffMask); }
Ini menghasilkan dua array:
Jika Anda mengisi array dengan karakter, itu bisa digunakan untuk menghitung perbedaan sebaris. Sekarang hanya satu langkah untuk menyoroti perbedaannya:
function diffline($line1, $line2) { $diff = computeDiff(str_split($line1), str_split($line2)); $diffval = $diff['values']; $diffmask = $diff['mask']; $n = count($diffval); $pmc = 0; $result = ''; for ($i = 0; $i < $n; $i++) { $mc = $diffmask[$i]; if ($mc != $pmc) { switch ($pmc) { case -1: $result .= '</del>'; break; case 1: $result .= '</ins>'; break; } switch ($mc) { case -1: $result .= '<del>'; break; case 1: $result .= '<ins>'; break; } } $result .= $diffval[$i]; $pmc = $mc; } switch ($pmc) { case -1: $result .= '</del>'; break; case 1: $result .= '</ins>'; break; } return $result; }
Misalnya.:
echo diffline('StackOverflow', 'ServerFault')
Akan menghasilkan:
S
tackOerverfFaulowtCatatan tambahan:
sumber
computeDiff is not found
Ada juga ekstensi PECL untuk xdiff:
Khususnya:
Contoh dari Manual PHP:
<?php $old_article = file_get_contents('./old_article.txt'); $new_article = $_POST['article']; $diff = xdiff_string_diff($old_article, $new_article, 1); if (is_string($diff)) { echo "Differences between two articles:\n"; echo $diff; }
sumber
Saya mengalami masalah besar dengan alternatif berbasis PEAR dan alternatif sederhana yang ditampilkan. Jadi, inilah solusi yang memanfaatkan perintah diff Unix (jelas, Anda harus menggunakan sistem Unix atau memiliki perintah Windows diff yang berfungsi agar berfungsi). Pilih direktori sementara favorit Anda, dan ubah pengecualian untuk mengembalikan kode jika Anda mau.
/** * @brief Find the difference between two strings, lines assumed to be separated by "\n| * @param $new string The new string * @param $old string The old string * @return string Human-readable output as produced by the Unix diff command, * or "No changes" if the strings are the same. * @throws Exception */ public static function diff($new, $old) { $tempdir = '/var/somewhere/tmp'; // Your favourite temporary directory $oldfile = tempnam($tempdir,'OLD'); $newfile = tempnam($tempdir,'NEW'); if (!@file_put_contents($oldfile,$old)) { throw new Exception('diff failed to write temporary file: ' . print_r(error_get_last(),true)); } if (!@file_put_contents($newfile,$new)) { throw new Exception('diff failed to write temporary file: ' . print_r(error_get_last(),true)); } $answer = array(); $cmd = "diff $newfile $oldfile"; exec($cmd, $answer, $retcode); unlink($newfile); unlink($oldfile); if ($retcode != 1) { throw new Exception('diff failed with return code ' . $retcode); } if (empty($answer)) { return 'No changes'; } else { return implode("\n", $answer); } }
sumber
Ini yang terbaik yang pernah saya temukan.
http://code.stephenmorley.org/php/diff-implementation/
sumber
$sequence1 = $string1; $sequence2 = $string2; $end1 = strlen($string1) - 1; $end2 = strlen($string2) - 1;
dengan$sequence1 = preg_split('//u', $string1, -1, PREG_SPLIT_NO_EMPTY); $sequence2 = preg_split('//u', $string2, -1, PREG_SPLIT_NO_EMPTY); $end1 = count($sequence1) - 1; $end2 = count($sequence2) - 1;
Apa yang Anda cari adalah "algoritma beda". Pencarian google cepat membawa saya ke solusi ini . Saya tidak mengujinya, tapi mungkin itu akan melakukan apa yang Anda butuhkan.
sumber
Port php Neil Frasers diff_match_patch (berlisensi Apache 2.0)
sumber
Saya akan merekomendasikan untuk melihat fungsi-fungsi luar biasa ini dari inti PHP:
Similar_text - Menghitung kesamaan antara dua string
http://www.php.net/manual/en/function.similar-text.php
levenshtein - Hitung jarak Levenshtein antara dua string
http://www.php.net/manual/en/function.levenshtein.php
soundex - Menghitung kunci soundex dari sebuah string
http://www.php.net/manual/en/function.soundex.php
metaphone - Hitung kunci metaphone dari sebuah string
http://www.php.net/manual/en/function.metaphone.php
sumber
Saya menemukan kelas diff PHP ini oleh Chris Boulton berdasarkan Python difflib yang bisa menjadi solusi yang baik:
PHP Diff Lib
sumber
Solusi lain (untuk perbandingan berdampingan sebagai lawan dari tampilan terpadu): https://github.com/danmysak/side-by-side .
sumber