|
|
|
|
![]() ![]() |
Nov 2 2006, 07:08 PM
Post
#1
|
|
|
Privileged Member ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Group: Members Posts: 535 Joined: 14-February 05 From: Oslo, Norway Member No.: 3,759 |
I need a script that compares 2 variables, and looks for a difference between them. It will then highlight the words that are different, as shown in the image below:
![]() So in the left cell, the yellow text is the text that has been removed OR replaced. In the right cell, the green text is the text that has replaced some text in the left cell, OR new text. This script will be used to compare 2 versions of a document stored in the database, to see the difference between each change (all revisions are stored in the database). I know that it's possible with PHP, because Wikipedia, which is coded in PHP, uses it, but I have absolutely no clue on how to do it. Any suggestions? Note: This was originally posted back here, but that topic seems dead, so I decided to make a new topic. |
|
|
|
Nov 2 2006, 08:01 PM
Post
#2
|
|
|
Advanced Member ![]() ![]() ![]() ![]() ![]() ![]() ![]() Group: Members Posts: 138 Joined: 30-September 06 From: Iasi, Romania Member No.: 30,851 |
CODE $string1 = "This is my first sentence"; $string2 = "This is my second sentence"; $find = explode(" ",$string1); foreach($find as $word){ $text = str_replace ($word, "<b>$word</b>", $string2); $string2=$text; } echo $text; this might be a starting point for you..it has flaws, as you will notice when you`ll run it ..also, it doesn't do exactly what you`ve asked for..well, just try it for yourself and maybe you`ll be able to modify it to fit your needs (ps: differences are bolded |
|
|
|
Nov 3 2006, 08:26 AM
Post
#3
|
|
|
Privileged Member ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Group: Members Posts: 535 Joined: 14-February 05 From: Oslo, Norway Member No.: 3,759 |
Well, I've never used foreach. And there is an error with your code. I entered these vars:
CODE $string1 = "test first and test again"; $string2 = "test second and test again"; And this is what it returns: CODE <b><b>test</b></b> second <b>and</b> <b><b>test</b></b> <b>again</b> On the words "test", there are two <b> tags, because the word "test" appears twice, and it actually highlights the words that are the same, not the words that are different. And there was another bug: CODE $string1 = "a variable is here"; $string2 = "a variable is there"; // Output: <b>a</b> v<b>a</b>ri<b>a</b>ble <b>is</b> t<b>here</b> So "a" is highlighted inside the word "variable" too. |
|
|
|
Nov 3 2006, 01:56 PM
Post
#4
|
|
|
Advanced Member ![]() ![]() ![]() ![]() ![]() ![]() ![]() Group: Members Posts: 138 Joined: 30-September 06 From: Iasi, Romania Member No.: 30,851 |
well yes, I knew about those errors..I`ve tested this script on my local server and the "a" letter was highlighted inside a word, too..sorry for this..I`ll think on this, as I might need it sometime later
|
|
|
|
Nov 3 2006, 04:51 PM
Post
#5
|
|
|
A computer once beat me at chess, but it was no match for me at kick boxing. ![]() Group: [MODERATOR] Posts: 4,083 Joined: 24-July 05 From: Linix, DOS and Windows…the good, the bad and the ugly Member No.: 9,787 ![]() |
After you explode the string, before you add the bold tags, make the array contain only unique entries.
I think the function is called array_unique(). Look on the php.net site for confirmation of the function and the details. |
|
|
|
Nov 6 2006, 04:56 AM
Post
#6
|
|
|
Premium Member ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Group: Members Posts: 162 Joined: 10-May 06 Member No.: 23,375 |
Well after exploding the same why dont you guys use the array_diff_assoc() function or the array_diff() function.
array_diff_assoc() function would be more appropriate though. QUOTE array_diff_assoc() returns an array containing all the values from array1 that are not present in any of the other arguments. Note that the keys are used in the comparison unlike array_diff(). CODE <?php $array1 = array("a" => "green", "b" => "brown", "c" => "blue", "red"); $array2 = array("a" => "green", "yellow", "red"); $result = array_diff_assoc($array1, $array2); print_r($result); ?> The above example will output: CODE Array ( [b] => brown [c] => blue [0] => red ) Well hope this will help in atleast finding the difference. But how will you arrange the thing I have not come up with that as yet. |
|
|
|
Nov 6 2006, 12:54 PM
Post
#7
|
|
|
Ephesians 6:10-17 ![]() Group: [MODERATOR] Posts: 1,918 Joined: 22-June 05 From: The World of Gentoo Member No.: 8,528 |
After hours of trial and error, i've managed to make a function that does almost exactly what you want!
EDIT: CODE function compare_contrast($var1, $var2){ $offset1 = preg_split('/\s/', $var1, -1, PREG_SPLIT_OFFSET_CAPTURE); $split1 = preg_split('/\s/', $var1); // $offset2 = preg_split('/\s/', $var2, -1, PREG_SPLIT_OFFSET_CAPTURE); $split2 = preg_split('/\s/', $var2); // $diff1 = array_diff_assoc($split1, $split2); $i = 0; foreach ($diff1 as $key => $value){ if ($i == 0){ $compare = substr_compare($var1, $offset1[$key][0], $offset1[$key][1], strlen($var1)); $compare = intval("-$compare"); $temp1 = substr_replace($var1, "<b>".$offset1[$key][0]."</b>", $offset1[$key][1], $compare); $i = $i + 7; } else { $compare = (strlen($var1)+$i) - (($offset1[$key][1]+$i) + strlen($offset1[$key][0])); $compare = intval("-$compare"); if ($compare < 0){ $temp1 = substr_replace($temp1, "<b>".$offset1[$key][0]."</b>", $offset1[$key][1]+$i, $compare); } else { $temp1 = substr_replace($temp1, "<b>".$offset1[$key][0]."</b>", $offset1[$key][1]+$i); } $i = $i + 7; } } // $diff2 = array_diff_assoc($split2, $split1); $i = 0; foreach ($diff2 as $key => $value){ if ($i == 0){ $compare = substr_compare($var2, $offset2[$key][0], $offset2[$key][1], strlen($var2)); $compare = intval("-$compare"); $temp2 = substr_replace($var2, "<b>".$offset2[$key][0]."</b>", $offset2[$key][1], $compare); $i = $i + 7; } else { $compare = (strlen($var2)+$i) - (($offset2[$key][1]+$i) + strlen($offset2[$key][0])); $compare = intval("-$compare"); if ($compare < 0){ $temp2 = substr_replace($temp2, "<b>".$offset2[$key][0]."</b>", $offset2[$key][1]+$i, $compare); } else { $temp2 = substr_replace($temp2, "<b>".$offset2[$key][0]."</b>", $offset2[$key][1]+$i); } $i = $i + 7; } } $output = array($temp1, $temp2); return $output; } This is the best i could get it as. If you're using PHP 4, then you'll need this as well: CODE if (!function_exists('substr_compare')){ function substr_compare($main_str, $str, $offset, $length = NULL, $case_insensitivity = false){ $offset = (int) $offset; // Throw a warning because the offset is invalid if ($offset >= strlen($main_str)){ trigger_error('The start position cannot exceed initial string length.', E_USER_WARNING); return false; } // We are comparing the first n-characters of each string, so let's use the PHP function to do it if ($offset == 0 && is_int($length) && $case_insensitivity === true){ return strncasecmp($main_str, $str, $length); } // Get the substring that we are comparing if (is_int($length)){ $main_substr = substr($main_str, $offset, $length); $str_substr = substr($str, 0, $length); } else { $main_substr = substr($main_str, $offset); $str_substr = $str; } // Return a case-insensitive comparison of the two strings if ($case_insensitivity === true){ return strcasecmp($main_substr, $str_substr); } // Return a case-sensitive comparison of the two strings return strcmp($main_substr, $str_substr); } } To output it use this: CODE $output = compare_contrast($str1, $str2);
echo $output[0]; echo $output[1]; |
|
|
|
Jan 18 2007, 06:30 PM
Post
#8
|
|
|
Privileged Member ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Group: Members Posts: 535 Joined: 14-February 05 From: Oslo, Norway Member No.: 3,759 |
Thanks a lot Truefusion, but there is still one bug: If a word has been added, it will highlight everything after the word. So the script wouldn't work correctly with this:
CODE $var1 = 'A web site with information and stuff'; $var2 = 'A web page with nice information and stuff'; page/site will be highlighted correctly, but I added the word "nice" in the second variable, so everything after that word has been highlighted. Any idea on how to fix that? This post has been edited by Amezis: Jan 18 2007, 06:32 PM |
|
|
|
![]() ![]() |