highlight substrings and full pattern regex matches
Posted: Thu Dec 20, 2007 1:13 am
Here is a function I made to highlight not only full pattern matches (yellow) but also all the substrings (multiple colors) from regex matches with preg_match_all(). The challenging part was figuring out a way to not only slip in the span tags, but html entity everything else. The code should explain itself, I used an array...
The problem is its not very quick on high # of full pattern matches and substring matches. Do you have an ideas/suggestions to quicken it, perhaps another method that can incorporate the highlighting + the html entitizing of the data?
You can see the function in action here:
http://tinyurl.com/2ynp8z
The problem is its not very quick on high # of full pattern matches and substring matches. Do you have an ideas/suggestions to quicken it, perhaps another method that can incorporate the highlighting + the html entitizing of the data?
You can see the function in action here:
http://tinyurl.com/2ynp8z
Code: Select all
<?php
function highlightPregHay($pat,$hay,$colors,$fullColor,$out = false) {
//out must be with preg_offset_capture flag, no special ordering
$hayLen = strlen($hay);
$matches = true;
$h = '';
if (!$out) {
$matches = preg_match_all($pat, $hay, $out, PREG_OFFSET_CAPTURE|PREG_SET_ORDER);
}
if ($matches) {
$lastOff = 0;
foreach ($out as $matchArr) { //each set of matches
$origFull = $matchArr[0][0]; //full pat match
$full = htmlentities($origFull);
$fullOff = $matchArr[0][1];
$fullLen = strlen($origFull);
unset($matchArr[0]);
if (!empty($matchArr)) {
$fullChars = str_split($origFull);
foreach ($fullChars as $k => $char) {
$fullChars[$k] = htmlentities($char);
}
$colorKey = -1;
foreach ($matchArr as $subInfoArr) { //each sub
$colorKey++;
$span = '<span style="background-color: '.$colors[$colorKey].';">';
$sub = $subInfoArr[0];
$subLen = strlen($sub);
$subOff = $subInfoArr[1] - $fullOff;
$endOff = ($subOff + $subLen) - 1;
$fullChars[$subOff] = $span.$fullChars[$subOff];
$fullChars[$endOff] .= '</span>';
}
$full = implode('',$fullChars);
}
//highlight the full in the haystack like before here
if ($fullOff == 0) {
$left = '';
} else {
$left = substr($hay, $lastOff, $fullOff-$lastOff);
}
$lastOff = $fullOff + $fullLen;
$h .= htmlentities($left).'<span style="background-color: '.$fullColor.';">'.$full.'</span>';
}
if ($lastOff < $hayLen) {
$h .= htmlentities(substr($hay, $lastOff));
}
return $h;
} else {
return false;
}
}
//substring colors
$colors[] = '#0066FF';
$colors[] = '#00FF66';
$colors[] = '#CC66FF';
$colors[] = '#FF0000';
$colors[] = '#FF9900';
$colors[] = '#99FFFF';
$colors[] = '#999999';
$colors[] = '#FF9966';
$colors[] = '#336699';
$colors[] = '#CC6666';
$colors[] = '#FF00CC';
$colors[] = '#CCFF99';
$colors[] = '#996633';
$colors[] = '#0099CC';
$colors[] = '#33CC33';
//full match color
$fullColor = '#FFFF00';
//regex
$pat = '~(hello) (how (are you (doi(ng t(oda)y, la) la) la this) is co)ol\!~';
$hay = 'hello how are you doing today, la la la this is cool! some more text';
echo highlightPregHay($pat,$hay,$colors,$fullColor);
?>