How match and mark several keywords in string with php - php

This is my current code:
# highlight keywords in string
function highlight($string, $keyword) {
return preg_replace("/".preg_quote($keyword)."/ui", "<span class=\"h\">$0</span>", $string);
}
If I execute this code:
$string = "The house is very big.";
echo highlight($string, "hous");
It will return:
The <span class="h">hous</span>e is very big.
Now I'm trying to send several keywords to the 2nd parameter of the function as an array, and all those matches should be highlighted. Example:
echo highlight($string, array("hous", "big");
...should return:
The <span class="h">hous</span>e is very <span class="h">big</span>.
Any ideas? Thanks.

Check if $keywords contains an array of values rather than being of a string type:
function highlight($string, $keywords) {
$keywords = is_array($keywords)
? implode('|', array_map('preg_quote', $keywords))
: preg_quote($keywords);
return preg_replace("/$keywords/ui", "<span class=\"h\">$0</span>", $string);
}
PHP live demo

You could simply do this:
function highlight($string, $keywords) {
return preg_replace("/".implode('|', $keywords)."/ui", "<span class=\"h\">$0</span>", $string);
}
$string = "The house is very big.";
echo highlight($string, ["hous", "big"]);
Note: implode('|', $keywords) since the | pipe symbol would allow you such flexibility.
For more insight, see: http://www.regular-expressions.info/alternation.html

Related

PHP check if two keywords occur in String

my challange explained on the following example: The keyword combination "gaming notebook" is given.
I want to check whether the two keywords occur in a string. The challange is that the string could look like this:
"Nice Gaming Notebook"
"Notebook for Gaming"
"Notebook for extreme Gaming"
I want my function to return true for all of the three strings. There is a tolerance of 3-4 words that can be between the word combination and as the examples show, I want it to work if the keywords are switched.
So my approach was the following, but it does not seem to work:
$keyword = strtolower("gaming notebook");
$parts = explode(" ", $keyword);
$string = strtolower("Which notebook for good gaming performance");
//point to end of the array
end($parts);
//fetch key of the last element of the array.
$lastElementKey = key($parts);
//iterate the array
$searchExpression = "";
foreach($parts as $k => $v) {
if($k != $lastElementKey) {
$searchExpression .= $v . "|";
} else {
$searchExpression .= $v;
}
}
if(preg_match_all('#\b('. $searchExpression .')\b#', $string, $matches) > 0) {
echo "Jep, keyword combination is in string";
} else {
echo "No, keyword combination is not in string";
}
You want to use something like CMU Sphinx or a natural language index in your database. (See http://dev.mysql.com/doc/refman/5.7/en/fulltext-natural-language.html) Doing a quick search of php libraries turned up "nlp-tools/nlp-tools," however, I have never used a pure php solution to accomplish what you are trying to do.
The solution using preg_match_all and array_intersect functions:
$keywordStr = "gaming notebook";
$string = "Which notebook for good gaming performance,it's my notebook";
$keywords = explode(" ", $keywordStr);
$parts = implode("|", $keywords);
preg_match_all("/\b$parts\b/i", $string, $matches);
// matched items should contain all needed keywords
if (count($keywords) == count(array_intersect($keywords, $matches[0]))) {
echo "Jep, keyword combination is in string";
} else {
echo "No, keyword combination is not in string";
}
<?php
$keyword = strtolower("gaming notebook");
$string = strtolower("Which notebooks for good gaming performance");
function check($keyword,$string){
$parts = explode(' ',$keyword);
$result = false;
$pattern = implode('|',$parts);
preg_match_all("(\b{$pattern}\b)",$string,$matches);
if(isset($matches[0])){
return true;
}
return false;
}
var_dump(check($keyword, $string));
$reg = "/(?:\b$kw1(?:\s+\w+){0,4}\s+$kw2\b)|(?:\b$kw2(?:\s+\w+){0,4}\s+$kw1\b)/";
if (preg_match($reg, $string)) {
echo "OK\n";
} else {
echo "KO\n";
}
This will echo OK when the 2 keywords occur in the string, in any order and separated by at most 4 words.
Explanation:
/
(?: : non capture group
\b$kw1 : keyword 1
(?:\s+\w+){0,4} : followed by 0 to 4 other word
\s+ : space(s)
$kw2\b : keyword 2
)
|
(?: : non capture group
\b$kw2 : keyword 2
(?:\s+\w+){0,4} : followed by 0 to 4 other word
\s+ : space(s)
$kw1\b : keyword 1
)
/

select multi numbers of words after # sign from using php

yesterday i asked a question that how to select specific word from string which is having # sign with it.
someone told me this solution
$abc = "hello #john what are you doing";
$found = preg_match('/#([^-\s]*)/', $abc, $matches);
$name = null;
if ($found) {
$name = $matches[1];
}
it works like a charm but the problem is it only select first word with # sign if the string have alot of words like that. so now i need a loop which selects all the words in string which are having # sign with them.
Use can use preg_match_all to get all matches of your regular expression, not just the first one.
$abc = "hello #john what on earth are #stella and #steve doing";
$found = preg_match_all('/#([^-\s]*)/', $abc, $matches);
if ($found) {
foreach ($matches[1] as $name) {
echo "Name: $name", PHP_EOL;
}
}
Output:
Name: john
Name: stella
Name: steve

How to Rename Uppercase Each Words with dash, underscore, brackets and capital words?

I want to rename the following statement:
<?php
$sentence = "I-am-a-GOOD-programmer-(but-only-in-PHP)";
$do = ucwords($sentence);
echo $do;
?>
the above code will give output as:
I-am-a-GOOD-programmer-(but-only-in-php)
How do I get the output as:
I-Am-A-Good-Programmer-(But-Only-In-Php)
$sentence = "I-am-a-good-programmer-(but-only-in-PHP)";
$sentence = preg_replace_callback('/(^|[-(])(\w+)/', function ($match) { return $match[1] . ucwords($match[2]); }, $sentence );
var_dump($sentence);
will result in:
string(40) "I-Am-A-Good-Programmer-(But-Only-In-PHP)"
^|[-(] means the beginning or either a - or ( and can be easily expanded with any other chars you need, alternatively you could your \W, which means any non-word character.
\w+ means word-character (alphabetical characters).
<?php
$msg = 'I-am-a-good-programmer-(but-only-in-PHP)';
$msg_replaced = preg_replace_callback('#([^\w]*)?(\w+)([^\w]*)?#', function($matched)
{
return $matched[1] . ucwords($matched[2]) . $matched[3];
}, $msg);
echo $msg_replaced;//I-Am-A-Good-Programmer-(But-Only-In-PHP)
?>
Found a solution to the problem:
<?php
$sentence = "I-am-a-GOOD-programmer-(but-only-in-PHP)";
$sentence = str_replace("-"," ",$sentence);
$do = ucfirst($sentence);
echo $do;
?>
Its gives output as I desired:
I Am A Good Programmer (But Only In Php)

Multiple word search and match using RegEx

I've created a function that highlights single words within a string. It looks like this:
function highlight($input, $keywords) {
preg_match_all('~[\w\'"-]+~', $keywords, $match);
if(!$match) { return $input; }
$result = '~\\b(' . implode('|', $match[0]) . ')\\b~i';
return preg_replace($result, '<strong>$0</strong>', $input);
}
I need the function to work with an array of different words supporting a space in the search.
Example:
$search = array("this needs", "here", "can high-light the text");
$string = "This needs to be in here so that the search variable can high-light the text";
echo highlight($string, $search);
Here's what I have so far to amend the function to work how I need it to:
function highlight($input, $keywords) {
foreach($keywords as $keyword) {
preg_match_all('~[\w\'"-]+~', $keyword, $match);
if(!$match) { return $input; }
$result = '~\\b(' . implode('|', $match[0]) . ')\\b~i';
$output .= preg_replace($result, '<strong>$0</strong>', $keyword);
}
return $output;
}
Obviously this doesn't work and I'm not sure how to get this to work (regular expression are not my strong point).
Another point that may be a problem, how would the function deal with a multiple match? Such as $search = array("in here", "here so"); as the result would be something like:
This needs to be <strong>in <strong>here</strong> so</strong> that the search variable can high-light the text
But this needs to be:
This needs to be <strong>in here so</strong> that the search variable can high-light the text
Description
Can you take your array of terms and join them with a regex or statement | then nest them into a string. The \b's would help ensure you're not capturing word fragments.
\b(this needs|here|can high-light the text)\b
Then run this as a replacement using the capture group \1?
Example
I'm not real familiar with Python, but in PHP I'd do something like this:
<?php
$sourcestring="This needs to be in here so that the search variable can high-light the text";
echo preg_replace('/\b(this needs|here|can high-light the text)\b/i','<strong>\1</strong>',$sourcestring);
?>
$sourcestring after replacement:
<strong>This needs</strong> to be in <strong>here</strong> so that the search variable <strong>can high-light the text</strong>

Preg Replace with mentions

I have some problems with the preg_replace.
I would change the mentions in a links but the name isn't a username.
So in the name there are spaces, i found a good solution but i don't know to do it.
Sostantially i would that preg_replace the words that are between # and ,
For example:
#John Doeh, #Jenna Diamond, #Sir Duck Norman
and replace to
VAL
How do I do it?
I think that you want it like:
John Doeh
For this try:
$myString="#John Doeh, #Jenna Diamond, #Sir Duck Norman";
foreach(explode(',',$myString) as $str)
{
if (preg_match("/\\s/", $str)) {
$val=str_replace("#","",trim($str));
echo "<a href='user.php?name=".$val."'>".$val."</a>";
// there are spaces
}
}
Based on my assumption you want to remove strings which start with #Some Name, in a text like: #Some Name, this is a message.
Then replace that to an href, like: First_Name
If that is the case then the following regex will do:
$str = '#First_Name, say something';
echo preg_replace ( '/#([[:alnum:]\-_ ]+),.*/', '$1', $str );
Will output:
First_Name
I also added support for numbers, underscores and dashes. Are those valid in a name aswell? Any other characters that are valid in a #User Name? Those are things that are important to know.
Two methods:
<?php
// preg_replace method
$string = '#John Doeh, #Jenna Diamond, #Sir Duck Norman';
$result = preg_replace('/#([\w\s]+),?/', '$1', $string);
echo $result . "<br>\n";
// explode method
$arr = explode(',', $string);
$result2 = '';
foreach($arr as $name){
$name = trim($name, '# ');
$result2 .= ''.$name.' ';
}
echo $result2;
?>

Categories