i have a system that outputs a film review, when it is outputted i want the keywords that appear in it from 2 tables - negative and positive to be in a different colour any idea to do this ? The code is below

<?php

// Connect to database
mysql_connect("sdd", "sdsd", "") or die(mysql_error());
mysql_select_db("sdsd") or die(mysql_error());

$id = mysql_real_escape_string($_POST['reviewid']); 

//$query = "select * from review where id = '$id'";
$query = mysql_fetch_assoc(mysql_query("SELECT filmreview FROM review WHERE id = '$id'"));
$pos = mysql_query("SELECT word FROM positive");
$neg = mysql_query("SELECT word FROM negative");


//Variables 
$review_text = $query['filmreview'];
$good = 0;
$bad = 0; 


// Gets words in to a text array and converts to lower case 
$cnt_r = array_count_values(array_map('mb_strtolower',str_word_count($review_text, 1)));

// Gets the positive words and check for the word in the text  
    while($check = mysql_fetch_assoc($pos)){
       $lower = mb_strtolower($check['word']);
     if(isset($cnt_r[$lower])){
    $good+= $cnt_r[$lower];
    echo $check ['word'];
    echo "<p>"; 
     } 
    }

// Gets the negative words and check for the word in the text 
while($check = mysql_fetch_assoc($neg)){
  $lower = mb_strtolower($check['word']);
 if(isset($cnt_r[$lower])){
    $bad+= $cnt_r[$lower];
        echo $check ['word'];
        echo "<p>";
 }  
} 


// If there are more positive words than negative than the review is positive  
if ($good > $bad)
{
    echo "<p>"; 
    echo "This is a positive review";
    echo "<p>";
}

// If there are more negative words than positive than the review is negative 
else if ($good < $bad)
{
    echo "<p>";
    echo "This is a negative review";
    echo "<p>";
}

// If there are the same amount of positive and negative words than the review is average 
else if ($good == $bad)
{
    echo "<p>";
    echo "This is an average review";
    echo "<p>";
}

//Prints out the number of postive and negative words found 
echo "Good words: " . $good . " and Bad words: " . $bad;
echo "<p>";
echo $query ['filmreview'];
echo "<p>";



echo "<form method='post' action='welcome.html'>";
echo "<input type='submit' name='searchagain' value='Search'>";
?>

Dani AI

Generated

Building on 's suggestion to wrap matches in spans with CSS, a single-pass replacement is the cleanest way to colour keywords inside each review when outputting a list. Fetch the positive/negative word lists once, build a lookup map, compile one alternation regex (longer phrases first, escaped with preg_quote), then run a single preg_replace_callback on each review. This avoids repeatedly looping the keyword lists and prevents injected markup from being re-matched.

Example (do the word-list queries once, then reuse the pattern for every review):

<?php
// $posRows and $negRows come from the DB queries
$pos = []; $neg = [];
while ($r = mysql_fetch_assoc($posRows)) $pos[] = $r['word'];
while ($r = mysql_fetch_assoc($negRows)) $neg[] = $r['word'];

$map = [];
foreach ($pos as $w) $map[mb_strtolower($w)] = 'pos';
foreach ($neg as $w) $map[mb_strtolower($w)] = 'neg';

$keywords = array_unique(array_merge($pos, $neg));
usort($keywords, function($a,$b){ return mb_strlen($b) - mb_strlen($a); });
$quoted = array_map(function($w){ return preg_quote($w,'/'); }, $keywords);
$pattern = '/(?<!\p{L})(' . implode('|',$quoted) . ')(?!\p{L})/iu';

while ($row = mysql_fetch_assoc($reviews)) {
  $text = $row['filmreview']; // operate on raw review text
  $highlighted = preg_replace_callback($pattern, function($m) use ($map) {
    $k = mb_strtolower($m[0]);
    $cls = (isset($map[$k]) && $map[$k] === 'pos') ? 'highlight-pos' : 'highlight-neg';
    return '<span class="'.$cls.'">'.$m[0].'</span>';
  }, $text);
  echo $highlighted;
}
?>

Notes and cautions:

  • Sort keywords by length first to avoid matching short words inside longer phrases.
  • Use preg_quote to escape special characters in keywords.
  • If reviews contain HTML, perform replacements only on text nodes (DOMDocument) or strip/escape tags first; otherwise replacements can break markup or highlight inside tags.
  • Build the pattern once (outside the reviews loop) for best performance, and consider caching results if there are many reviews.
  • Modernize DB code (mysqli or PDO with prepared statements) and always sanitize output; keep CSS for .highlight-pos and .highlight-neg in a stylesheet.

This approach wraps matches inline (so highlighted words appear inside each review), ties back to 's span/CSS idea, and is efficient for multiple-review output.

Recommended Answers

All 10 Replies

Member Avatar for Member #120589
// Gets the positive words and check for the word in the text  
    while($check = mysql_fetch_assoc($pos)){
       $lower = mb_strtolower($check['word']);
     if(isset($cnt_r[$lower])){
    $good+= $cnt_r[$lower];
    echo "<p class=\"goodword\">{$check['word']}</p>";
     } 
    }
 
// Gets the negative words and check for the word in the text 
while($check = mysql_fetch_assoc($neg)){
  $lower = mb_strtolower($check['word']);
 if(isset($cnt_r[$lower])){
    $bad+= $cnt_r[$lower];
        echo "<p class=\"badword\">{$check['word']}</p>"
 }  
}

In your css file or style section in the head tag:

.goodword{
  color: green;
}
.badword{
  color: red;
}

i want the words to appear coloured in the text outputted not individually

ive added this but doesnt seem to work

if($pos) {  
       $newpostivekeyword = "<p class=\"goodword\">{$pos['word']}</p>";
   }
    if($neg) {  
      $newnegativekeyword = "<p class=\"badword\">{$neg['word']}</p>";
    }
	
	$new_review_text = str_replace($newpostivekeyword, $newnegativekeyword, $review_text);
	echo $new_review_text;
Member Avatar for Member #120589
<?php
// Connect to database
mysql_connect("sdd", "sdsd", "") or die(mysql_error());
mysql_select_db("sdsd") or die(mysql_error());
 
$id = mysql_real_escape_string($_POST['reviewid']); 
 
//$query = "select * from review where id = '$id'";
$query = mysql_fetch_assoc(mysql_query("SELECT filmreview FROM review WHERE id = '$id'"));
$pos = mysql_query("SELECT word FROM positive");
$neg = mysql_query("SELECT word FROM negative");
 
 
//Variables 
$review_text = $query['filmreview'];
$good = 0;
$bad = 0; 
 
 
// Gets words in to a text array and converts to lower case 
$cnt_r = array_count_values(array_map('mb_strtolower',str_word_count($review_text, 1)));
 
// Gets the positive words and check for the word in the text  
while($check = mysql_fetch_assoc($pos)){
	$lower = mb_strtolower($check['word']);
    if(isset($cnt_r[$lower])){
    	$good+= $cnt_r[$lower];
    	echo "<p>" . $check['word'] . "</p>";
    	$review_text = preg_replace("/\b{$check['word']}\b/", "<span class=\"goodword\">{$check['word']}</span>" , $review_text);
    } 
}
 
// Gets the negative words and check for the word in the text 
while($check = mysql_fetch_assoc($neg)){
	$lower = mb_strtolower($check['word']);
 	if(isset($cnt_r[$lower])){
    	$bad+= $cnt_r[$lower];
    	echo "<p>" . $check['word'] . "</p>";
    	$review_text = preg_replace("/\b{$check['word']}\b/", "<span class=\"badword\">{$check['word']}</span>" , $review_text);
 	}  
} 
 
 
// If there are more positive words than negative than the review is positive  
if ($good > $bad)
{
    echo "<p>"; 
    echo "This is a positive review";
    echo "<p>";
}
 
// If there are more negative words than positive than the review is negative 
else if ($good < $bad)
{
    echo "<p>";
    echo "This is a negative review";
    echo "<p>";
}
 
// If there are the same amount of positive and negative words than the review is average 
else if ($good == $bad)
{
    echo "<p>";
    echo "This is an average review";
    echo "<p>";
}
 
//Prints out the number of postive and negative words found 
echo "Good words: " . $good . " and Bad words: " . $bad;
echo "<p>";
echo $review_text;
echo "<p>";
echo "<form method='post' action='welcome.html'>";
echo "<input type='submit' name='searchagain' value='Search'>";
?>

not tested

seems to be working thanks a lot

hi, i just wanted to ask going back to this question if i am output one review like:

while($row = mysql_fetch_array($data))
	{
		echo "<table border=\"2\" align=\"left\">";
		echo "<tr><td>";
		echo "<b>Review Title:</b> " .$row['reviewtitle'];
		echo "<tr><td>";
		echo $row['filmreview'];
		echo "<p>";	
		echo "<form method='post' action='analyse.php'>";
		echo "<input type='hidden' name='reviewid' value='".$row['id']."'>";
		echo "<input type='submit' name='submit' value='Analyse'>";
		echo "</form>";		
		echo "</table>";
	}

how can i apply the colours for pos and neg words ?

Member Avatar for Member #120589

My previous post showed you how to apply a span with a specific classname.

SO in your style tag (or CSS file):

.badword{
  color: red;
}
.goodword{
  color: green;
}

//EDIT - just saw - I've already posted that information. :(

yep that worked fine but that was only outputting one review, for this its outputting a list of reviews, i just want to output the review with the words highlighted

Member Avatar for Member #120589

Looking at your code again, you've just got an output from the DB and plonked it along with a form onto the page. Sorry, it's getting late, but I can't see how this code is fundamentally different to the previous examples. Don't you just need to apply the preg_replaces using the data from the goodword and badword tables?

ok i will try that and see what happens, it is similar to as before but when i click a button it analyses one review but i want to output all reviews

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.