Highlight the difference between two strings in PH

2018-12-31 09:19发布

What is the easiest way to highlight the difference between two strings in PHP?

I'm thinking along the lines of the Stack Overflow edit history page, where new text is in green and removed text is in red. If there are any pre-written functions or classes available, that would be ideal.

12条回答
弹指情弦暗扣
2楼-- · 2018-12-31 09:48

Just wrote a class to compute smallest (not to be taken literally) number of edits to transform one string into another string:

http://www.raymondhill.net/finediff/

It has a static function to render a HTML version of the diff.

It's a first version, and likely to be improved, but it works just fine as of now, so I am throwing it out there in case someone needs to generate a compact diff efficiently, like I needed.

Edit: It's on Github now: https://github.com/gorhill/PHP-FineDiff

查看更多
不再属于我。
3楼-- · 2018-12-31 09:52
梦醉为红颜
4楼-- · 2018-12-31 09:55

You can use the PHP Horde_Text_Diff package. It suits your needs, and is quite customisable as well.

It's also licensed under the GPL, so Enjoy!

查看更多
还给你的自由
5楼-- · 2018-12-31 09:55

This is a nice one, also http://paulbutler.org/archives/a-simple-diff-algorithm-in-php/

Solving the problem is not as simple as it seems, and the problem bothered me for about a year before I figured it out. I managed to write my algorithm in PHP, in 18 lines of code. It is not the most efficient way to do a diff, but it is probably the easiest to understand.

It works by finding the longest sequence of words common to both strings, and recursively finding the longest sequences of the remainders of the string until the substrings have no words in common. At this point it adds the remaining new words as an insertion and the remaining old words as a deletion.

You can download the source here: PHP SimpleDiff...

查看更多
浅入江南
6楼-- · 2018-12-31 10:00

I had terrible trouble with the both the PEAR-based and the simpler alternatives shown. So here's a solution that leverages the Unix diff command (obviously, you have to be on a Unix system or have a working Windows diff command for it to work). Choose your favourite temporary directory, and change the exceptions to return codes if you prefer.

/**
 * @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);
  }
}
查看更多
孤独寂梦人
7楼-- · 2018-12-31 10:00

What you are looking for is a "diff algorithm". A quick google search led me to this solution. I did not test it, but maybe it will do what you need.

查看更多
登录 后发表回答