Search engine - before string and after - php

A have something like this. It works fine, but I have been tried 2 hours to cut search result - 100 str before $word and 100 after.
How can I make this?
$word = $_POST["search"];
$sql_events = mysql_query("SELECT * FROM events WHERE event_title LIKE '%" . $word . "%' OR event_desc LIKE '%" . $word ."%'");
function highlightWords($content, $word){
if(is_array($search)){
foreach ( $search as $word ){
$content = str_ireplace($word1, '<span>'.$word1.'</span>', $content);
}
} else {
$content = str_ireplace($word, '<span>'.$word.'</span>', $content);
}
return $content;
}
while($row = mysql_fetch_array($sql_events)){
$content = $row["event_desc"];
$result = highlightWords($content, $word);
echo '<li>
<H3>'.$row['event_title'].'</H3>
<div class="text">'.$result .'...</div>
</li>';
}

You need this regular expression:
[\d\D]{0,100}word[\d\D]{0,100}
Where word is the main word :). Here it is implemeted with your code:
$content = $row["event_desc"];
$word_in_regexp = quotemeta($content);
preg_match("/[\d\D]{0,100}$word_in_regexp[\d\D]{0,100}/i", $content, $matches);
$content = $matches[0];
We use quotemeta() in case $content contains characters like [, (, \ etc.

$wordpos1 = (mb_strpos($content, $word) - 100);
if ($wordpos1 < 0){
$wordpos1 = 0;
} else {
$wordpos1 = (mb_strpos($content, $word) - 100);
}
$wordpos2 = (mb_strpos($content, $word) + 400);
$resText = mb_substr($content, $wordpos1, $wordpos2);
$result = highlightWords($resText, $word);
And it's works to me :)

Related

Find a phrase in a string

My code below is working
<?php
//load synonyms of words
$json_file = fopen("dict.json", "r") or die("Unable to open file!");
$js = fread($json_file, filesize("dict.json"));
$json = json_decode($js, true);
$text = "Hello my friend, today i am feeling good.";
$ar_text = explode(" ", $text);
foreach ($ar_text as $val)
{
$rand = rand(1, 3);
$randx = rand(1, 3);
if ($rand == $randx)
{
if (array_key_exists($val, $json))
{
$null = "{" . $val . "|";
$inc = $json[$val]['sinonim'];
$i = 1;
foreach ($inc as $siap)
{
$null .= $siap . "|";
if ($i == 4) break;
$i++;
}
$null .= "}";
$text = str_replace(" $val ", " $null ", $text);
//echo $null."<br>";
}
else
{
//echo "not found ".$val."<br>";
}
}
//echo $val;
}
$text = str_replace("|}", "}", $text);
echo $text;
//echo $json['mengaras']['tag'];
?>
i use explode to get word by word and then replace with word synonyms, how to get a phrase like "really good" and find it on dict.json.
Example: Hello, i am really good right now.
Output: Hello, i am {so fine|super fine|superb} now.
Use str_replace() - Replace all occurrences of the search string with the replacement string
$text = "Hello, i am really good right now.";
$find = "really good";
$replace = "so fine|super fine|superb";
$newtext= str_replace($find, $replace, $text);
OUTPUT:
Hello, i am so fine|super fine|superb right now.
You can do it this way too:
$text = 'Hello, i am really good right now.';
$match = 'really good';
$match_len = strlen($match);
$replace = array("so fine","super fine", "superb");
$pos = strpos($text, $match);
if($pos !== false){
echo "Word Found!";
$replace = implode("|", $replace);
$embed = '{' . $replace . '}';
echo $text_before . ' ' . $embed . ' ' . $text_after;
} else{
echo "Word Not Found!";
}
Output
Hello, i am {so fine|super fine|superb} right now.

preg_replace() with a string contains "*" character

I have made a script to highlight a word in a string. The script is below.
function highlight_text($text, $words){
$split_words = explode( " " , $words );
foreach ($split_words as $word){
$color = '#FFFF00';
$text = preg_replace("|($word)|Ui", "<span style=\"background:".$color.";\">$1</span>", $text );
}
return $text;
}
$text = '*bc';
$words = '*';
echo highlight_text($text, $words);
When running the script, I got the following error:
Warning: preg_replace(): Compilation failed: nothing to repeat at offset 1
Can anyone help me?
This can help you:
<?php
function highlight_text($text, $words){
$split_words = explode( " " , $words );
foreach ($split_words as $key=>$word){
if (preg_match('/[\'^£$%&*()}{##~?><>,|=_+¬-]/', $word))// looking for special characters
{
$word = preg_quote($word, '/');// if found output \ before that
}
$color = '#FFFF00';
$text = preg_replace("|($word)|Ui", "<span style=\"background:".$color.";\">$1</span>", $text );
}
return $text;
}
$text = '*bc';
$words = '*';
echo highlight_text($text, $words);
change "*" to "\*" and profit.
You can check if special character in function highlight_text
like:
function highlight_text($text, $words){
$split_words = explode( " " , $words );
foreach ($split_words as $word){
$str = '';
$word = str_split($word);
foreach ($word as $c) {
if ($c == '*') {
$str .= '\*';
}
else {
$str .= $c;
}
}
$color = '#FFFF00';
$text = preg_replace("|($str)|Ui", "<span style=\"background:".$color.";\">$1</span>", $text );
}
return $text;
}
Change your code to
function highlight_text($text, $words){
$split_words = explode( " " , $words );
foreach ($split_words as $word){
$color = '#FFFF00';
$word = preg_quote($word, '/');
$text = preg_replace("|$word|Ui", "<span style=\"background:".$color.";\">$0</span>", $text );
}
return $text;
}
$text = '*bc';
$words = '*';
echo highlight_text($text, $words);
then will be ok.

PHP how to find uppercase in array

I have an array with many words, but some senteces are in uppercase. For example:
THIS SENTENCE IS UPPERCASE
this sentece is in lowercase
And I want to split this two sentences by \r\n, but I cant find how to do it
Here is how I retrive this array:
$result_pk_info = array();
while ($row = odbc_fetch_array($sql_pk_info))
{
$opisanie = iconv("cp1257", "UTF-8", trim($row['opis']));
$id = iconv("cp1257", "UTF-8", trim($row['pacientid']));
$date = iconv("cp1257", "UTF-8", trim($row['data']));
$desc = explode('##$', $opisanie);
$all_info = "<tr><td>".$desc[1]."</td></tr>";
$result_pk_info[] = $all_info;
}
in $desc I have words array in which I want to search and split uppercase and lowercase.
So can anyone help me with it?
UPD the text which I have hase something like this structure:
SENTENCE IN UPPERCASE Sentece in lower case
This function is what you're looking for :
function split_upper_lower ($string)
{
$words = explode (' ', $string);
$i = 0;
foreach ($words as $word)
{
if (ctype_upper ($word))
$new_string_array[++$i]['type'] = 'UPPER';
else
$new_string_array[++$i]['type'] = 'LOWER';
$new_string_array[$i]['word'] = $word;
}
$new_string = '';
foreach ($new_string_array as $key => $new_word)
{
if (!isset ($current_mode))
{
if (ctype_upper ($new_word))
$current_mode = 'UPPER';
else
$current_mode = 'LOWER';
}
if ($new_word['type'] === $current_mode)
{
$new_string .= $new_word['word'];
if (isset ($new_string_array[$key + 1]))
$new_string .= ' ';
}
else
{
$new_string .= "\r\n" . $new_word['word'];
if (isset ($new_string_array[$key + 1]))
$new_string .= ' ';
if ($current_mode === 'UPPER') $current_mode = 'LOWER';
else $current_mode = 'UPPER';
}
}
return $new_string;
}
Tested it with br :
$string = 'HI how ARE you doing ?';
echo split_upper_lower ($string);
Output :
HI
how
ARE
you doing ?
Use preg_match: http://php.net/manual/en/function.preg-match.php
$string = 'THIS SENTENCE IS UPPERCASE';
$string2 = 'this sentece is in lowercase';
if(preg_match ( '/[A-Z ]$/' , $string))
{
echo 'uppercase';
}
else
{
echo 'lowercase';
}
Use this in your loop through $desc. Where $string is one element of an array containing one string.
/[A-Z ]$/ will match all uppercase with spaces. You can just upgrade your regexp to grab something else from strings.
If I understood your question you can do like this ...
$desc = array ("abcd","ABCD","bbb","B");
foreach($desc as $value) {
if(ctype_upper($value)) {
// character is upper
} else {
// character is lower
}
}
This can be done using preg_match_all(). Use the following code,
$result_pk_info = array();
while ($row = odbc_fetch_array($sql_pk_info))
{
$opisanie = iconv("cp1257", "UTF-8", trim($row['opis']));
$id = iconv("cp1257", "UTF-8", trim($row['pacientid']));
$date = iconv("cp1257", "UTF-8", trim($row['data']));
$desc = explode('##$', $opisanie);
//converting $desc array to string
$string = implode(" " , $desc);
//Upper case Matching
$upprCase = preg_match_all('/[A-Z]/', $string, $uprmatches, PREG_OFFSET_CAPTURE);
if($upprCase){
foreach ($uprmatches as $match)
{
foreach($match as $value)
//Iam a uppercase
print $UpperCase = $value[0];
}}
//Splitting with \r\n
print "\r\n";
//lower case matching
$lowrCase = preg_match_all('/[a-z]/', $string, $lowrmatches, PREG_OFFSET_CAPTURE);
if($lowrCase){
foreach ($lowrmatches as $match)
{
foreach($match as $value)
//Iam a lowercase
print $lowerCase = $value[0];
}}
}

Function ShortenTitle

I'm developing within Wordpress but my PHP knowledge is minimal, The title is showing only the 1st word, how to I change it? this is where I believe its being restricted to the 1st word.
function ShortenTitle($title){
// Change to the number of characters you want to display
$chars_max = 100;
$chars_text = strlen($title);
$title = $title."";
$title = substr($title,0,$chars_max);
$title = substr($title,0,strrpos($title,' '));
if ($chars_title > $chars_max)
{
$title = $title."...";
}
return $title;
}
function limit_content($str, $length) {
$str = strip_tags($str);
$str = explode(" ", $str);
return implode(" " , array_slice($str, 0, $length));
}
The trim function removes whitespace from the end of the string, I assume this is what you are trying to do with this
$title = substr($title,0,strrpos($title,' '));
Also, you should probably trim before computing the length, just to be safe/accurate. Try this:
function ShortenTitle($title){
// Change to the number of characters you want to display
$chars_max = 100;
$new_title = substr(trim($title),0,$chars_max);
if (strlen($title) > strlen($new_title)) {
$new_title .= "...";
}
return $new_title;
}
if ($chars_title > $chars_max) should be if ($chars_text > $chars_max)
Try this:
function ShortenTitle($title) {
$title = trim($title);
$chars_max = 100;
if (strlen($title) > $chars_max) {
$title = substr($title, 0, $chars_max) . "...";
}
return $title;
}
Cleaned it up a bit.

how to highlight search results

hello i have a search function in that i will search a db for keywords. i would like to highlight the keywords and found a second function that i would like to implement into my search function.
so i have this code for the search:
<?php
function searchText($keywords){
global $db;
$returned_results = array();
$where2 = "";
$keywords = preg_split('/[\s]+/', $keywords);
$total_keywords = count($keywords);
foreach ($keywords as $key=>$keyword){
$where2 .= "`column` LIKE '%$keyword%'";
if ($key != ($total_keywords - 1)){
$where2 .= " OR ";
}
}
$results_text = "SELECT `a`, `b`, LEFT(`c`, 150) as `c` FROM `table` WHERE $where2";
$results_num_text = ($query2 = mysqli_query($db, $results_text)) ? mysqli_num_rows($query2) : 0;
if ($results_num_text === 0){
return false;
} else {
while ($row = mysqli_fetch_assoc($query2)){
$returned_results[] = array(
'ab' => $row['ab'],
'cd' => $row['cd'],
);
}
return $returned_results;
}
}
?>
and would like to implement a second function into it:
<?php
function mark_words ($text, $words, $colors = false)
{
if (!$colors || !is_array($colors) ) {
$colors = array('#ff9999', '#ffff99', '#ff99ff', '#99ffff','#99ff99');
}
$c = 0;
foreach ($words as $w) {
$w = preg_quote(trim($w));
if($w=='') {
continue;
}
$regexp = "/($w)(?![^<]+>)/i";
$replacement = '<b style="background-color:'.$colors[$c].'">\\1</b>';
$text = preg_replace ($regexp,$replacement ,$text);
$c++;
if ($c >= count($colors)) {
$c=0;
}
}
return $text;
}
$example = <<< EOT
some text is here inside
EOT;
$search = array('some','is', 'inside');
echo mark_words($example, $search);
?>
so i have this code that doesnt work:
<?php
function searchText($keywords, $colors = false){
global $db;
if (!$colors || !is_array($colors) ) {
$colors = array('#ff9999', '#ffff99', '#ff99ff', '#99ffff','#99ff99');
}
$c = 0;
$returned_results = array();
$where2 = "";
$keywords = preg_split('/[\s]+/', $keywords);
$total_keywords = count($keywords);
foreach ($keywords as $key=>$keyword){
$regexp = "/($w)(?![^<]+>)/i";
$replacement = '<b style="background-color:'.$colors[$c].'">\\1</b>';
$text = preg_replace($regexp,$replacement ,$keywords);
$c++;
if ($c >= count($colors)) {
$c=0;
}
$where2 .= "`b` LIKE '%$keyword%'";
if ($key != ($total_keywords - 1)){
$where2 .= " OR ";
}
}
$results_text = "SELECT `a`, LEFT(`b`, 150) as `b`, `c` FROM `table` WHERE $where2";
$results_num_text = ($query2 = mysqli_query($db, $results_text)) ? mysqli_num_rows($query2) : 0;
if ($results_num_text === 0){
return false;
} else {
while ($row = mysqli_fetch_assoc($query2)){
$returned_results[] = array(
'ab' => $row['a'],
'cd' => $row['b'],
);
}
return $returned_results;
$highlight = array($keywords);
echo mark_words($highlight);
}
}
?>
as i looked for it how to do so i found two possibilities. the first would be a function the second would be directly to highlight it from the select query:
SELECT
REPLACE(`col`, 'foobar', '<span class="highlight">foobar</span>') AS `formated_foobar`
FROM
…
WHERE
`col` LIKE "%foobar%"
so my question is how can i implement the second function into the search function or would it be better to use the second method?
if there is someone who could help me i really would appreciate. thanks a lot.
You shouldn't make it too hard for yourself. All you need it to replace every occurrence of a word with the word wrapped in the span with the required style applied. This should work for you:
function highlight_word( $content, $word, $color ) {
$replace = '<span style="background-color: ' . $color . ';">' . $word . '</span>'; // create replacement
$content = str_replace( $word, $replace, $content ); // replace content
return $content; // return highlighted data
}
function highlight_words( $content, $words, $colors ) {
$color_index = 0; // index of color (assuming it's an array)
// loop through words
foreach( $words as $word ) {
$content = highlight_word( $content, $word, $colors[$color_index] ); // highlight word
$color_index = ( $color_index + 1 ) % count( $colors ); // get next color index
}
return $content; // return highlighted data
}
// words to find
$words = array(
'normal',
'text'
);
// colors to use
$colors = array(
'#88ccff',
'#cc88ff'
);
// faking your results_text
$results_text = array(
array(
'ab' => 'AB #1',
'cd' => 'Some normal text with normal words isn\'t abnormal at all'
), array(
'ab' => 'AB #2',
'cd' => 'This is another text containing very normal content'
)
);
// loop through results (assuming $output1 is true)
foreach( $results_text as $result ) {
$result['cd'] = highlight_words( $result['cd'], $words, $colors );
echo '<fieldset><p>ab: ' . $result['ab'] . '<br />cd: ' . $result['cd'] . '</p></fieldset>';
}
Using Regular Expressions to replace content would do as well, though using str_replace() is a bit faster.
The functions accepts these arguments:
highlight_word( string, string, string );
highlight_words( string, array, array );
The above example results in:
By using str_ireplace instead of str_replace, the function will work case insensitive
I would not use the SQL method. As time goes on, and you have more and more highlighting rules, that will become unmanageable. Also trickier to handle the cases where you need to highlight foo differently to foobar, but one contains the other.
Separate your data handling from your formatting.

Categories