I have the following :
Sentence :
"This is a red apple"
pattern to check :
red & apple.
Both sentence and pattern to check are user generated.
$sentence = "This is a red apple";
$words = array('red','apple');
$ch = implode("|",$words);
$pattern = '/[$ch]/';
if(preg_match($pattern, $sentence))
{
// Do something if the sentence contains red & apple
}
When i execute that code, i get nothing (nothing is displayed). When i do echo on $pattern it returns it as a whole string instead.
How can i fix this ? What am i missing ?
change $pattern = '/[$ch]/';
to
$pattern = '/('.$ch.')/'; or $pattern = '/['.$ch.']';
<?php
$sentence = "This is a red apple";
$words = array('apple','red');
$ch = implode("|",$words);
echo $pattern = '/('.$ch.')/';
if(preg_match($pattern, $sentence))
{
echo ' Do something if the sentence contains red & apple';
}else
{
echo 'nothing happpen';
}
?>
check if both word match
<?php
$sentence = "This is a red apple";
$words = array('red','apple');
$ch = implode("|",$words);
echo $pattern = '['.$ch.']';
if(preg_match_all($pattern, $sentence,$matches) == 2)
{
echo ' Do something if the sentence contains red & apple';
}else
{
echo 'nothing happpen';
}
?>
You also check how many word matched using
echo count($matches[0]);
$matches is array contain word are matched
You need to take care about quotes while using variables within quotes you need to update
$pattern = '/[$ch]/';
into
$pattern = "/($ch)/";
^^ ^^ ^^ ^^
You need to update your regex pattern also, so your code looks like as
$sentence = "This is a red apple";
$words = array('red','apple');
$ch = implode("|",$words);
$pattern = "/($ch)/";
if(preg_match_all($pattern, $sentence,$m))
{
echo "yes \n";
print_r($m);
}
Instead of regex I'll use array_intersect along with str_word_count like as
$sentence = "This is a red apple";
$words = array('red','apple','blue');
$var = count(array_intersect(str_word_count($sentence,1),$words));
if(count($words == $var)){
echo "Yes got it";
}
Demo
Demo2
Related
I am trying to check if word is occur in a string but not to be the first and last word, if its true then remove the space after and before of the word and replace with a underscore.
Input:
$str = 'This is a cool area";
Output:
$str = 'This is a_cool_area";
I want to check that the word 'cool' is inside the string but not a first and last word. if yes the remove the space & replace with '_'
You can use preg_replace to do this job, using this regex:
/(?<=\w)\s+(' . $word . ')\s+(?=\w)/i
which looks for the word, surrounded by at least one word character on either side (to prevent matching at the beginning or ending of the sentence). Usage in PHP:
$str = 'This is a cool area';
$word = 'cool';
$str = preg_replace('/(?<=\w)\s+(' . $word . ')\s+(?=\w)/i', '_$1_', $str);
echo $str . "\n";
$str = ' Cool areas are cool ';
$str = preg_replace('/(?<=\w)\s+(' . $word . ')\s+(?=\w)/i', '_$1_', $str);
echo $str . "\n";
Output:
This is a_cool_area
Cool areas are cool
Demo on 3v4l.org
function checkWord($str, $word)
{
$arr = explode(" ", $str);
$newArr = array_slice($arr, 1, -1);
$key = array_search($word, $newArr);
if($key !== false)
{
return implode('_',array_slice($arr, $key, 3));
}
else
{
return $str;
}
}
echo checkWord('This is a cool area', 'cool');
I have a search String: $str (Something like "test"), a wrap string: $wrap (Something like "|") and a text string: $text (Something like "This is a test Text").
$str is 1 Time in $text. What i want now is a function that will wrap $str with the wrap defined in $wrap and output the modified text (even if $str is more than one time in $text).
But it shall not output the whole text but just 1-2 of the words before $str and then 1-2 of the words after $str and "..." (Only if it isn`t the first or last word). Also it should be case insensitive.
Example:
$str = "Text"
$wrap = "<span>|</span>"
$text = "This is a really long Text where the word Text appears about 3 times Text"
Output would be:
"...long <span>Text</span> where...word <span>Text</span> appears...times <span>Text</span>"
My Code (Obviusly doesnt works):
$tempar = preg_split("/$str/i", $text);
if (count($tempar) <= 2) {
$result = "... ".substr($tempar[0], -7).$wrap.substr($tempar[1], 7)." ...";
} else {
$amount = substr_count($text, $str);
for ($i = 0; $i < $amount; $i++) {
$result = $result.".. ".substr($tempar[$i], -7).$wrap.substr($tempar[$i+1], 0, 7)." ..";
}
}
If you have a tipp or a solution dont hesitate to let me know.
I have taken your approach and made it more flexible. If $str or $wrap changes you could have escaping issues within the regex pattern so I have used preg_quote.
Note that I added $placeholder to make it clearer, but you can use $placeholder = "|" if you don't like [placeholder].
function wrapInString($str, $text, $element = 'span') {
$placeholder = "[placeholder]"; // The string that will be replaced by $str
$wrap = "<{$element}>{$placeholder}</{$element}>"; // Dynamic string that can handle more than just span
$strExp = preg_quote($str, '/');
$matches = [];
$matchCount = preg_match_all("/(\w+\s+)?(\w+\s+)?({$strExp})(\s+\w+)?(\s+\w+)?/i", $text, $matches);
$response = '';
for ($i = 0; $i < $matchCount; $i++) {
if (strlen($matches[1][$i])) {
$response .= '...';
}
if (strlen($matches[2][$i])) {
$response .= $matches[2][$i];
}
$response .= str_replace($placeholder, $matches[3][$i], $wrap);
if (strlen($matches[4][$i])) {
$response .= $matches[4][$i];
}
if (strlen($matches[5][$i]) && $i == $matchCount - 1) {
$response .= '...';
}
}
return $response;
}
$text = "text This is a really long Text where the word Text appears about 3 times Text";
string(107) "<span>text</span> This...long <span>text</span> where...<span>text</span> appears...times <span>text</span>"
To make the replacement case insensitive you can use the i regex option.
If I understand your question correct, just a little bit of implode and explode magic needed
$text = "This is a really long Text where the word Text appears about 3 times Text";
$arr = explode("Text", $text);
print_r(implode('<span>Text</span>', $arr));
If you specifically need to render the span tags using HTML, just write it that way
$arr = explode("Text", $text);
print_r(implode('<span>Text</span>', $arr));
Use patern below to get your word and 1-2 words before and after
/((\w+\s+){1,2}|^)text((\s+\w+){1,2}|$)/i
demo
In PHP code it can be:
$str = "Text";
$wrap = "<span>|</span>";
$text = "This is a really long Text where the word Text appears about 3 times Text";
$temp = str_replace('|', $str, $wrap); // <span>Text</span>
// find patern and 1-2 words before and after
// (to make it casesensitive, delete 'i' from patern)
if(preg_match_all('/((\w+\s+){1,2}|^)text((\s+\w+){1,2}|$)/i', $text, $match)) {
$res = array_map(function($x) use($str, $temp) { return '... '.str_replace($str, $temp, $x) . ' ...';}, $match[0]);
echo implode(' ', $res);
}
Objective: strings with ' should match the string without it.
Example:
$first_string = "alex ern o'brian";
$second_string = "alex-ern o brian";
$pattern = array("/(-|\.| )/", "/(')/");
$replace = array(' ', '(\s|)');
$first_string = preg_replace($pattern, $replace, $first_string);
$second_string = preg_replace($pattern, $replace, $second_string);
$first_string_split = preg_split("/(-|\.| )/", $first_string);
$first_string_split[] = $first_string;
$second_string_split = preg_split("/(-|\.| )/", $second_string);
$second_string_split[] = $second_string;
$first_string = array_slice($first_string_split, -1)[0];
$second_string = array_slice($second_string_split, -1)[0];
if(in_array($first_string, $second_string_split) || in_array($second_string, $first_string_split))
{
echo 'true';
} else {
echo 'false';
}
I think you are expecting this.
Solution 1: Try this code snippet here
Regex: (\s|) this will match either space or null.
<?php
ini_set('display_errors', 1);
$string = "o'brian";
$string=str_replace("'", "(\s|)",$string);
$list = array("o'neal", "o brian", "obrian");
$result=array();
foreach($list as $value)
{
if(preg_match("/$string/", $value))
{
$result[]=$value;
}
}
print_r($result);
Solution 2:
Regex: [a-z]+ will match character from a to z.
$string1="o brian";
$string2="obrian";
if(preg_match("/".implode(" ", $matches[0])."/", $string1))
{
echo "matched";
}
if( preg_match("/".implode("", $matches[0])."/", $string2))
{
echo "matched";
}
I'm not sure if I got your question right, but this should do it:
(?<=\w)'(?=\w)
It matches every ' character, which is followed and preceded by a word character. The word character \w is equal to [a-zA-Z0-9_].
Here is a live example to test the regex
Here is a live PHP example
I have a string and some words, i want to highlight those words which match with string, and also i want to print only those words which are highlighted, like if apple matches, then only apple must be printed.
$string = "apple computer";
$keyword = "apple,orange,bike";
I am using the following function to highlight specific characters in a string.
$str = preg_replace("/($keyword)/i","<span style='color:orange;'>$0</span>",$string);
The problem is I want to show only those characters which are highlighted, currently it shows all the characters.
This would meet your need.
$string = " apple computer orange";
$keywords = "apple, orange";
$exp_kwd = explode(",", $keywords);
$res = "<span style='color:orange;'>";
foreach($exp_kwd as $val){
if(strpos($string, trim($val))){
$res .= $val." ";
}
}
$res = $res."</span>";
echo $res;
Hopefully this also will work
$string = "apple computer orange tested";
$keyword = "apple,orange,bike,tested";
$pattern="/".str_replace(",","/,/",$keyword)."/";
$pattern=explode(",",$pattern);
$string=explode(" ",$string);
$keyword =explode(",",$keyword);
$string=implode(",",(preg_filter($pattern, $keyword, $string)));
echo $string="<span style='color:orange;'>$string</span>";
$string = "Im On #Here";
$keyword = "#";
$var = strrchr($string,$keyword);
if(empty($var))
{
echo 'No Occerunce Found';
}
else
{
echo '<span style="color:orange;">'.$var.'</span>';
}
phpfiddle Preview
Is there any way to tell if a preg_replace was successful or not?
I tried:
<?php
$stringz = "Dan likes to eat pears and his favorite color is green and green!";
$patterns = array("/pears/","/green/", "/red/");
if ($string = preg_replace($patterns, '<b>\\0</b>', $stringz, 1)) {
echo "<textarea rows='30' cols='100'>$string</textarea>";
}else{
echo "Nope. You didn't have all the required patterns in the array.";
}
?>
and yes, I looked at php docs for this one. Sorry about my stupid questions earlier.
You can use the last param of preg_replace: &$count, which will contain the number of replacements that were done:
$stringz = "Dan likes to eat pears and his favorite color is green and green!";
$patterns = array("/pears/","/green/","/green/");
$new_patterns = array();
foreach ($patterns as $p)
if (array_key_exists($p, $new_patterns))
$new_patterns[$p]++;
else
$new_patterns[$p] = 1;
$string = $stringz;
$success = TRUE;
foreach ($new_patterns as $p => $limit)
{
$string = preg_replace($p, '<b>\\0</b>', $string, $limit, $count);
if (!$count)
{
$success = FALSE;
break;
}
}
if ($success)
echo "<textarea rows='30' cols='100'>$string</textarea>";
else
echo "Nope. You didn't have all the required patterns in the array.";
edited to fix the issue when there are two of the same in $patterns
if (preg_replace($patterns, '<b>$0</b>', $stringz, 1) != $stringz)
echo 'preg_replace was successful'
From the documentation:
If matches are found, the new subject
will be returned, otherwise subject
will be returned unchanged or NULL if
an error occurred.
So:
$string = preg_replace($patterns, '<b>\\0</b>', $stringz, 1);
if($string != $stringz) {
// something was replaced
}