/    Sign up×
Community /Pin to ProfileBookmark

Differences Script

I’ve looked through several resources and could not come up with something, so I thought I would ask you guys if you knew of a script to do what I want, or have any thoughts on how to build one.

I am going to have a MySQL table with 2 text fields. I want to generate a differences report between the text fields.

One mthod I thought of would be to explode each field by spaces. Then, loop through the field2 array. If the array item matches the same array item in the field1 array item, then advance the array key. If it does not match, add an opening span, and advance the field2 array only. Once they match up again, clase the span and continue on.

Problem I see, this method only produces output where field2 has additional words that field1 does not. It does not take into account any deletions.

I guess I could do the opposite for the other field and then display each field with highlighted text that is not contained in the other one. But, I’d rather have all the difference higlights be located in only one displayed field.

Any suggestions on how to proceed, or know of any scripts that do this?

to post a comment
PHP

7 Comments(s)

Copy linkTweet thisAlerts:
@NogDogDec 15.2006 — You might want to take a look at the array_diff() and array_intersect() functions to see if they help.
Copy linkTweet thisAlerts:
@ShmohelauthorDec 15.2006 — Thanks. I will take a look into that.
Copy linkTweet thisAlerts:
@sitehatcheryDec 15.2006 — I havent' tested this and it's just off the top of my head. There's probably a much more efficient way of doing this, but at least it's a discussion catalyst.
[code=php]
$string1="some value";
$string2="This is the value";
$diff=array();
$str1=explode(' ',$string1);
foreach($str1 as $key=>$val){
if(strpos($str2, $val)){ $diff[]=$val; next($diff);
}
[/code]
Copy linkTweet thisAlerts:
@ShmohelauthorDec 15.2006 — I pulled this script from discussions on php.net under the array_diff function:

[code=php]<?php
function diff_rek(&$a1,&$a2,$D,$k,&$vbck)
{
$x=$vbck[$D][$k]; $y=$x-$k;
if ($D==0)
{
if ($x==0) return array(array(),array());
else
return array(array_slice($a1,0,$x),array_fill(0,$x,"b"));
}
$x2=$vbck[$D-1][$k+1];
$y2=$vbck[$D-1][$k-1]-($k-1);
$xdif=$x-$x2; $ydif=$y-$y2;
$l=min($x-$x2,$y-$y2);
$x=$x-$l;
$y=$y-$l;
if ($x==$x2)
{
$res=diff_rek($a1,$a2,$D-1,$k+1,$vbck);
array_push($res[0],$a2[$y-1]);
array_push($res[1],"2");
if ($l>0)
{
$res[0]=array_merge($res[0],array_slice($a2,$y,$l));
$res[1]=array_merge($res[1],array_fill(0,$l,"b"));
}
}
else
{
$res=diff_rek($a1,$a2,$D-1,$k-1,$vbck);
array_push($res[0],$a1[$x-1]);
array_push($res[1],"1");
if ($l>0)
{
$res[0]=array_merge($res[0],array_slice($a1,$x,$l));
$res[1]=array_merge($res[1],array_fill(0,$l,"b"));
}
}
return $res;
}

function arr_diff(&$a1,&$a2)
{
$max=70;
$c1=count($a1);
$c2=count($a2);
$v[1]=0;
for ($D=0; $D<=$max; $D++)
{
for ($k=-$D; $k<=$D; $k=$k+2)
{
if (($k==-$D) || ($k!=$D && $v[$k-1]<$v[$k+1]))
$x=$v[$k+1];
else
$x=$v[$k-1]+1;
$y=$x-$k;
while (($x<$c1)&&($y<$c2)&&($a1[$x]==$a2[$y]))
{
$x++;
$y++;
}
$v[$k]=$x;
if (($x>=$c1)&&($y>=$c2))
{
$vbck[$D]=$v;
return diff_rek($a1,$a2,$D,$c1-$c2,$vbck);
};
}
$vbck[$D]=$v;
};
return -1;
}

echo "<html><body bgcolor=white>";

$oldString = "Once there was a boy named Bart and a girl named Lisa.";
$newString = "Once upon a time there was a girl named Lisa.";

echo "Old String: " . $oldString . "<br>";
echo "New String: " . $newString . "<br>";
echo "Difference: " . diff_to_html($oldString, $newString);
// Returns a nicely formatted html string
function diff_to_html($oldString, $newString)
{
$a1 = explode(" ", $oldString);
$a2 = explode(" ", $newString);
$result = arr_diff($a1, $a2);

foreach ($result[0] as $num => $foo)
{
$source = $result[1][$num];
$element = $result[0][$num];

switch ($source)
{
case "1":
$pre = "<font color=red><s>";
$post = "</s></font>";
break;
case "2":
$pre = "<font color=green>";
$post = "</font>";
break;
case "b":
$pre = "";
$post = "";
break;
}
// VERTICAL OUTPUT:
// $return .= $num . $pre . " " . $source .
// " " . $element . $post . "<br>";
// READABLE OUTPUT:
$return .= $pre . $element . $post . " ";
}
return $return;
}

?>[/code]


For my need, I am probably going to take what is here and tweak some.
Copy linkTweet thisAlerts:
@sitehatcheryDec 15.2006 — Modification. Tested, it works.

[code=php]
$string1="some value";
$string2="This is the value";
$diff=array();
$str1=explode(' ',$string1);
foreach($str1 as $key=>$val){
if(strpos($string2, $val)){ $diff[]=$val; next($diff);}
}

foreach($diff as $key=>$val){
echo $val;
}
[/code]
Copy linkTweet thisAlerts:
@NightShift58Dec 16.2006 — I think - but am not certain - that I've understood what it is that you want to do. At the risk of embarrassing myself, here's a shot in the dark:
[code=php]<?
$string1 = "the lazy brown fox";
$string2 = "jumped over the lazy brown dog";

$arrSTR1 = explode(" ", $string1);
$arrSTR2 = explode(" ", $string2);

$arrDIFF = array();

foreach ($arrSTR1 as $thisWORD) :
$arrDIFF[$thisWORD]++;
endforeach;

foreach ($arrSTR2 as $thisWORD) :
$arrDIFF[$thisWORD]++;
endforeach;

print "<pre>";
print_r($arrDIFF);
print "</pre>";
?>[/code]


This will produce the following output:
[code=php]Array
(
[the] => 2
[lazy] => 2
[brown] => 2
[fox] => 1
[jumped] => 1
[over] => 1
[dog] => 1
)[/code]

The resulting array, [B]$arrDIFF[/B], will contain all the words found in [B]both[/B] strings. Any word with a value of 1 is unique and anything with a 2 or more is a duplicate, i.e. exists in both strings.

Is that even close to where you wanted to go?
Copy linkTweet thisAlerts:
@ShmohelauthorDec 16.2006 — yea . . . it is. Thanks for the help. That looks like a good way to do it, and with some tweaks I think I could get that to where I want it.
×

Success!

Help @Shmohel spread the word by sharing this article on Twitter...

Tweet This
Sign in
Forgot password?
Sign in with TwitchSign in with GithubCreate Account
about: ({
version: 0.1.9 BETA 5.18,
whats_new: community page,
up_next: more Davinci•003 tasks,
coming_soon: events calendar,
social: @webDeveloperHQ
});

legal: ({
terms: of use,
privacy: policy
});
changelog: (
version: 0.1.9,
notes: added community page

version: 0.1.8,
notes: added Davinci•003

version: 0.1.7,
notes: upvote answers to bounties

version: 0.1.6,
notes: article editor refresh
)...
recent_tips: (
tipper: @AriseFacilitySolutions09,
tipped: article
amount: 1000 SATS,

tipper: @Yussuf4331,
tipped: article
amount: 1000 SATS,

tipper: @darkwebsites540,
tipped: article
amount: 10 SATS,
)...