views:

278

answers:

2

Consider the following string:

this is a STRING WHERE some keywords ARE available. 'i need TO format the KEYWORDS from the STRING'

In the above string keywords are STRING and WHERE

Now i need to get an output as follows:

this is a <b>STRING</b> <b>WHERE</b> some keywords ARE available. 'i need TO format the KEYWORDS from the STRING'

So that the html output will be like:

this is a STRING WHERE some keywords ARE available. 'i need TO format the KEYWORDS from the STRING'

Note that the keywords within a quoted ('...') string will be ignored. in the above example i ignored the STRING keyword within the quoted string.

Please give a modified version of the following PHP script so that I can have my desired result as above :

$patterns = array('/STRING/','/WHERE/');
$replaces = array('<b>STRING</b>', '<b>WHERE</b>');
$string   = "this is a STRING WHERE some keywords ARE available. 'i need TO format the KEYWORDS from the STRING'";
preg_replace($patterns, $replaces, $string);
A: 

Try something like:

$keywords = array(
  'STRING' ,
  'WHERE' ,
  'KEYWORDS'
);
$keywordsRE = array();
foreach( $keywords as $w ) {
  $keywordsRE[] = '/\b('.$w.')\b/';
}
$string = "this is a STRING WHERE some keywords KEYWORDS ARE available. 'i need TO format the KEYWORDS from the STRING'";
$stringParts = explode( "'" , $string );
foreach( $stringParts as $k => $v ) {
  if( !( $k%2 ) )
    $stringParts[$k] = preg_replace( $keywordsRE , '<b>$1</b>' , $v );
}
$stringReplaced = implode( "'" , $stringParts );

Repeating the same keywords (with the same changes) is a bit redundant - using a Regular Expression allows you to apply those same changes (in this case, wrapping the matches in <b></b> tags) to all matches.

Lucanos
It's an imperfect solution, and a little hacky, but it works. And I have changed the `$string` variable's contents to prove that (ie "KEYWORDS" being seen both inside and outside of the excluded zone)
Lucanos
+2  A: 

This will work with your string example, but there will be problems with more complicated strings, for example those containing words with apostrophes. Anyway, it may be used as a starting point.

$keywords = array("STRING", "WHERE");
$regexp = '/(\'[^\']+\')|\b(' . implode('|', $keywords) . ')\b/e';
preg_replace($regexp, "strlen('\\2') ? '<b>\\2</b>' : '\\0'", $string);
Alexander Konstantinov
WOW! nice solution. Would you please explain that what is the meaning of \b and \\2.Although, if i consider another quote like `` including '' (means two quotes) what will be the script?Thanks a lot... :)
Saiful
\b - word boundary, i.e. position in the string where one of the chars is a letter (or digit or "_"), an the other one - not a letter.\0, \1, \2 - the text captured by the n'th parenthesized pattern: \1 - contents of the first pair of regex parentheses (in this case - the quoted substring), \2 - contents of the second pair (in this case - one of the keywords), \0 - the whole matched string (in this case it equals to whether \1 or \2)
Alexander Konstantinov
But does this solution ignore the text contained within a pair of single quotation marks, as per the OP?
Lucanos
great! thanks a lot for the explanation.
Saiful