Намиране на думи в текст

bancov96

Registered
Здравейте, колеги. Надрасках набързо една функция за намиране на думи в стринг и подчертаването им, за да я използвам в една форма за търсене на продукти:

Код:
function highlight($str, $search = '') {
    if (strlen($search) > 0) {
        $search = preg_quote($search);
        return preg_replace("/($search)/iu", "<span style='color: #000000; background-color: #FFFF00;'>\\1</span>", $str);
    } else {
        return $str;
    }
}

Тук обаче идва проблемът, че търси по точен низ, а ако напиша в полето за търсене няколко думи, например: "диск метал", няма да подчертае думите "диск" и "метал" ако съществуват поотделно.

Някой има ли идея как да напиша функция, която да взима думите от даден стринг, без значение дали са отделени със запетая, интервал, два интервала или прочие и да ги подчертава с даден цвят ако ги намери в даден стринг? Функцията трябва да не се влияе от главни/малки букви и да съвместима със знаци на кирилица.

Надявам се, че сте ме разбрали. Благодаря предварително. :?:
 
Код:
<?php

$string = "Imalo edno       wreme,na zapad!";
$tags = "Imalo edno, zapad";
$newArray = array();

$array = preg_split( '/\s+|,\s+|,|\!\s+|\!|\.\s+|\.|\?\s+|\?/', $string );
$arrayMatch = preg_split('/\s+|,\s+|,|\!\s+|\!|\.\s+|\.|\?\s+|\?/', $tags);

$array = array_map("trim", $array);
$arrayMatch = array_map("trim", $arrayMatch);

for($i = 0; $i < count($arrayMatch); $i++)
    for($j = 0; $j < count($array); $j++)
        if($array[$j] == $arrayMatch[$i])
            $newArray[] = $array[$j];

echo "<pre>";
print_r($newArray);
echo "</pre>";

Кода съм го написал супер подробно, за да хванеш логиката!
$string са ти думите
$tags са ти таговете
$newArray е масива с намерените съвпадения от първоначалните 2 масива.

Регулярния израз ти е на възможно най-ниско ниво. Разделя по интервал, запетая, точка, въпросителен, удивителен! Ако искаш да добавим още или правиш сам, или пишеш отново тук.
\s - интервал
+ множество от дадения символ
\ пред ., !, ?... ескейпва, за да не правят проблем запазените символи.
| или

Има как да го пипнеш доста, но ще ти трябва много четене, че изразите са тънка линия.

Ако желаеш думите да са стилизирание просто в намереното съвпадение от дума добавяш стилизация <strong>$array[$i]<strong>.

Отностно оптимизация всичко зависи от това как ще извеждаш. Ако добавяш директно <strong> то тогава при if-a пипаш кода. Ако ще работиш с масиви за по-голяма гъвкавост, може да погледнеш in_array(), array_replace()...

Поздрави!
 
Благодаря много за помощта. Остана само един проблем. Възможно ли да е не прави разлика между малки и големи букви. Ето пренаписания от мен код:

PHP:
<?php

function highlight($string, $keywords) {
	$newArray = array();

	$array = preg_split( '/\s+|,\s+|,|\!\s+|\!|\.\s+|\.|\?\s+|\?/', $string);
	$arrayMatch = preg_split('/\s+|,\s+|,|\!\s+|\!|\.\s+|\.|\?\s+|\?/', $keywords);

	$array = array_map('trim', $array);
	$arrayMatch = array_map('trim', $arrayMatch);

	for($i = 0; $i < count($arrayMatch); $i++) {
		 for($j = 0; $j < count($array); $j++) {
			if($array[$j] == $arrayMatch[$i]) {
				$newArray[] = $array[$j];
			}
		}
	}

	foreach($newArray as $a) {
		$string = preg_replace('/' . $a . '/iu', '<strong>' .$a. '</strong>', $string);
	}

	return $string;
}

echo highlight('Левски е най-великият отбор!', 'ЛЕВСКИ');

Горния код не подчертава думата "Левски", макар че съществува в стринга (макар и не изцяло с главни букви). str_replace и str_ireplace не вършат работа със знаци на кирилица. Някакви идеи?
 
Код:
$array = preg_split( '/\s+|\s+\,|\,\s+|\,|\!\s+|\!|\.\s+|\.|\?\s+|\?/iu', $string, 0, PREG_SPLIT_NO_EMPTY );
$arrayMatch = preg_split('/\s+|\,\s+|\,|\!\s+|\!|\.\s+|\.|\?\s+|\?/iu', $tags, 0, PREG_SPLIT_NO_EMPTY);

новите регулярни

Код:
for($i = 0; $i < count($arrayMatch); $i++)
    for($j = 0; $j < count($array); $j++) {
        $tmp = $array[$j];
        if(mb_convert_case($array[$j], MB_CASE_LOWER, "UTF-8") == mb_convert_case($arrayMatch[$i], MB_CASE_LOWER, "UTF-8"))
            $newArray[] = $tmp;
    }

новите цикли
$tmp помни непроменената дума от първия стринг


Поздрави!
 

Back
Горе