issus with emoji in array - php

In this code, when I use ":-)" emoji doesn't show in output.
But when use "1f60a" OR "1f60c" OR "e252" emoji are shown. What's the problem?
<?php
$emoji_url = "http://coremobile.ir/images_smileys";
$emoji_style = "";
$emoji_code = array(
":-)",
"1f60a",
"1f60c",
"e252"
);
$emoji_img = array(
'<img src="'.$emoji_url.'/1f60a.png" '.$emoji_style.'>',
'<img src="'.$emoji_url.'/1f60a.png" '.$emoji_style.'>',
'<img src="'.$emoji_url.'/1f60c.png" '.$emoji_style.'>',
'<img src="'.$emoji_url.'/e252.png" '.$emoji_style.'>'
);
$ret = 'This Test :-) 1f60a';
$ret = str_replace($emoji_code, $emoji_img, $ret);
echo $ret;
?>

This should work for you:
(Just use strtr() instead of str_replace(), so that it won't go through the string multiple times)
$ret = strtr($ret, array_combine($emoji_code, $emoji_img));
output:
This Test
The otherone didn't worked, because it replaced every match for the first replacement and then the second and so on.
0 replaced:
This Test :-) 1f60a
//^^^ match
first replaced:
This Test <img src="http://coremobile.ir/images_smileys/1f60a.png" > 1f60a
//^^^^^ match ^^^^^ match
second replaced:
This Test <img src="http://coremobile.ir/images_smileys/<img src="http://coremobile.ir/images_smileys/1f60a.png" >.png" > <img src="http://coremobile.ir/images_smileys/1f60a.png" >

Related

Regex replace keyword with different string by loop (PHP)

Let say I have a string
$content = "hello . wow . cool . yes!";
It's easy to just replace the dot to another string:
echo preg_replace("/\./", "<img>", $content);
so the output is:
hello <img> wow <img> cool <img> yes!
however, is there any way to replace it one by one?
for example, I have an array and would like to insert them into the string.
$arr = ['<img src="a"/>', '<img src="b"/>', '<img src="c"/>'];
the expected output:
hello <img src="a"/> wow <img src="b"/> cool <img src="c"/> yes!
I can use preg_match_all to get the separator but still have no idea how to replace it respectively.
Thank you for any help.
Use preg_replace_callback. Store the number of the current full stop in a static variable. Access $arr from the callback with use (). Use modulo in case there are not enough items in $arr.
<?php
$content = 'hello . wow . cool . yes!';
$arr = ['<img src="a"/>', '<img src="b"/>', '<img src="c"/>'];
$content = preg_replace_callback ('/\./', function ($_) use ($arr) {
static $count = 0;
return $arr [$count++ % count ($arr)];
}, $content);
echo ($content);
http://sandbox.onlinephpfunctions.com/code/f9115bdb6eb17e30012d987ed1fc4b95e7c10d33.

PHP Using str_replace along with preg_replace

I have a string of comma separated values that comes from a database, which actually are image paths. Like so:
/images/us/US01021422717777-m.jpg,/images/us/US01021422717780-m.jpg,/images/us/US01021422717782-m.jpg,/images/us/US01021422718486-m.jpg
I then do like below, to split them at the , and convert them into paths for the web page.
preg_replace('~\s?([^\s,]+)\s?(?:,|$)~','<img class="gallery" src="$1">', $a)
Works well, but in one place further in my page, I need to change the -m to -l (which means large)
When I do like below (put a str_replace inside the preg_replace), nothing happens. How can I do something like this?
preg_replace('~\s?([^\s,]+)\s?(?:,|$)~','<img class="gallery" src="$1" data-slide="'.str_replace('-m','-l','$1').'">', $a)
You're putting the str_replace() call in the output pattern for the preg_replace() call. That means preg_replace() is treating it as literal text.
What you want is something like this:
$imgtag = preg_replace(match, replacement, $a);
$imgtag = str_replace('-m','-l',$imgtag);
But, in my opinion it would be safer and easier to debug this stuff if you changed the order of your replacement operations, something like this:
foreach ($path in explode(",", $a)) {
$path = str_replace('-m','-l',$path);
$imgtag= sprintf ('<img class="gallery" src="%s">', $path);
/* do something with the $imgtag */
}
That way you don't have to whistle into your modem :-) to program that regexp.
Use str_replace on preg_replace return
$large = str_replace('-m','-l', preg_replace('~\s?([^\s,]+)\s?(?:,|$)~','<img class="gallery" src="$1">', $a));
Output will be
<img class="gallery" src="/images/us/US01021422717777-l.jpg">
<img class="gallery" src="/images/us/US01021422717780-l.jpg">
<img class="gallery" src="/images/us/US01021422717782-l.jpg">
<img class="gallery" src="/images/us/US01021422718486-l.jpg">
Use preg_replace_callback():
preg_replace_callback(
'~\s?([^\s,]+)\s?(?:,|$)~',
function (array $matches) {
$src = $matches[1]; // this is "$1"
$slide = str_replace('-m', '-l', $matches[1]);
return '<img class="gallery" src="'.$src.'" data-slide="'.$slide.'">';
},
$a
);
Instead of the replace expression, preg_replace_callback() gets as its second argument a function that receives the list of matched expressions and returns the replacement string.
Actually your str_replace is simply invoked before preg_replace is invoked. Result of str_replace is then passed as argument to preg_replace.
What I could suggest is using preg_replace_callback:
function replace_img($match)
{
return '<img class="gallery" src="' .
$match[1] .
'" data-slide="' .
str_replace('-m','-l',$match[1]) .
'">';
}
preg_replace_callback('~\s?([^\s,]+)\s?(?:,|$)~','replace_img', $a);
If you need two separate outputs from each comma-separated value, I would write a pattern that stores the fullstring match and the substrings on either side of the m in each file.
*note: I match the trailing - in the first capture group and the leading . in the second capture group for minimal assurance of accuracy. This is somewhat weak validation; you can firm it up if your project requires it by adding literal or more restrictive pattern components in the capture groups.
Code: (Demo)
$csv='/images/us/US01021422717777-m.jpg,/images/us/US01021422717780-m.jpg,/images/us/US01021422717782-m.jpg,/images/us/US01021422718486-m.jpg';
if(preg_match_all('~([^,]+-)m(\.[^,]+)~',$csv,$out,PREG_SET_ORDER)){
foreach($out as $m){
$mediums[]="<img class=\"gallery\" src=\"{$m[0]}\">";
$larges[]="<img class=\"gallery\" src=\"{$m[0]}\" data-slide=\"{$m[1]}l{$m[2]}\">";
}
}
var_export($mediums);
echo "\n\n";
var_export($larges);
Output:
array (
0 => '<img class="gallery" src="/images/us/US01021422717777-m.jpg">',
1 => '<img class="gallery" src="/images/us/US01021422717780-m.jpg">',
2 => '<img class="gallery" src="/images/us/US01021422717782-m.jpg">',
3 => '<img class="gallery" src="/images/us/US01021422718486-m.jpg">',
)
array (
0 => '<img class="gallery" src="/images/us/US01021422717777-m.jpg" data-slide="/images/us/US01021422717777-l.jpg">',
1 => '<img class="gallery" src="/images/us/US01021422717780-m.jpg" data-slide="/images/us/US01021422717780-l.jpg">',
2 => '<img class="gallery" src="/images/us/US01021422717782-m.jpg" data-slide="/images/us/US01021422717782-l.jpg">',
3 => '<img class="gallery" src="/images/us/US01021422718486-m.jpg" data-slide="/images/us/US01021422718486-l.jpg">',
)

Replace string with different strings containing pattern

Say you have a string like
$str = "<img src='i12'><img src='i105'><img src='i12'><img src='i24'><img src='i15'>....";
is it possible to replace every i+n by the nth value of an array called $arr
so that for example <img src='i12'> is replaced by <img src='$arr[12]'>.
If I were you, I'd simply parse the markup, and process/alter it accordingly:
$dom = new DOMDocument;
$dom->loadHTML($str);//parse your markup string
$imgs = $dom->getElementsByTagName('img');//get all images
$cleanStr = '';//the result string
foreach($imgs as $img)
{
$img->setAttribute(
'src',
//get value of src, chop of first char (i)
//use that as index, optionally cast to int
$array[substr($img->getAttribute('src'), 1)]
);
$cleanStr .= $dom->saveXML($img);//get string representation of node
}
echo $cleanStr;//echoes new markup
working demo here
Now in the demo, you'll see the src attributes are replaced with a string like $array[n], the code above will replace the values with the value of an array...
I would use preg_replace for this:
$pattern="/(src=)'\w(\d+)'/";
$replacement = '${1}\'\$arr[$2]\'';
preg_replace($pattern, $replacement, $str);
$pattern="/(src=)'\w(\d+)'/";
It matches blocks of text like src='letter + digits'.
This catches the src= and digit blocks to be able to print them back.
$replacement = '${1}\'\$arr[$2]\'';
This makes the replacement itself.
Test
php > $str = "<img src='i12'><img src='i105'><img src='i12'><img src='i24'><img src='i15'>....";
php > $pattern="/(src=)'\w(\d+)'/";
php > $replacement = '${1}\'\$arr[$2]\'';
php > echo preg_replace($pattern, $replacement, $str);
<img src='$arr[12]'><img src='$arr[105]'><img src='$arr[12]'><img src='$arr[24]'><img src='$arr[15]'>....

php preg_match_all and preg_replace.

[caption id="attachment_1342" align="alignleft" width="300" caption="Cheers... "Forward" diversifying innovation to secure first place. "][/caption] A group of 35 students from...
I'm reading this data from api. I want the text just start with A group of 35 students from.... Help me to replace the caption tag with null. This is what I tried:
echo "<table>";
echo "<td>".$obj[0]['title']."</td>";
echo "<td>".$obj[0]['content']."</td>";
echo "</table>";
$html = $obj[0]['content'];
preg_match_all('/<caption>(.*?)<\/caption>/s', $html, $matches);
preg_replace('',$matches, $obj[0]['content']);
Any help.
$pattern = "/\[caption (.*?)\](.*?)\[\/caption\]/i";
$removed = preg_replace($pattern, "", $html);
echo preg_replace("#\[caption.*\[/caption\]#u", "", $str);
In the snippet mentioned in the question, regex search pattern is incorrect. there is no <caption> in the input. its <caption id....
Second using preg_replace doesn't serve any purpose here. preg_replace expects three arguments. first should be a regex pattern for search. second the string to replace with. and third is input string.
Following snippet using preg_match will work.
<?php
//The input string from API
$inputString = '<caption id="attachment_1342" align="alignleft" width="300" caption="Cheers... "Forward" diversifying innovation to secure first place. "></caption> A group of 35 students from';
//Search Regex
$pattern = '/<caption(.*?)<\/caption>(.*?)$/';
//preg_match searches inputString for a match to the regular expression given in pattern
//The matches are placed in the third argument.
preg_match($pattern, $inputString, $matches);
//First match is the whole string. second if the part before caption. third is part after caption.
echo $matches[2];
// var_dump($matches);
?>
if you still want to use preg_match_all for some reason. following snippet is modification of the one mentioned in question -
<?php
//Sample Object for test
$obj = array(
array(
'title' => 'test',
'content' => '<caption id="attachment_1342" align="alignleft" width="300" caption="Cheers... "Forward" diversifying innovation to secure first place. "></caption> A group of 35 students from'
)
);
echo "<table border='1'>";
echo "<td>".$obj[0]['title']."</td>";
echo "<td>".$obj[0]['content']."</td>";
echo "</table>";
$html = $obj[0]['content'];
//preg_match_all will put the caption tag in first match
preg_match_all('/<caption(.*?)<\/caption>/s', $html, $matches2);
//var_dump($matches2);
//use replace to remove the chunk from content
$obj[0]['content'] = str_replace($matches2[0], '', $obj[0]['content']);
//var_dump($obj);
?>
Thank you guys. I use explode function to do this.
$html = $obj[0]['content'];
$code = (explode("[/caption]", $html));
if($code[1]==''){
echo $code[1];
}

preg_replace : how get what is replaced

I want to show cards from regex codes :
ah displays As of hearts,
kc displays King of clubs
...
I used preg_replace() to do that in this way :
$arr = array('ah', 'kh', 'qh', ..., '3c', '2c');
$regex = '';
foreach ($arr as $i => $card)
{
$regex .= $card;
if ($i < count($arr) - 1)
$regex .= '|';
}
$message = preg_replace('#('.$regex.')#', '<img src="'.$dontknow.'.png" class="card" alt="" />', $message);
I don't know what value put in the src attribute, I want to tell to preg_replace() "when you find 'ah' you put ah.png, if it's kc then $dontknow == 'kc' etc.
Someone could be bring me some help ?
You can do this:
$message = preg_replace('#('.$regex.')#',
'<img src="$1.png" class="card" alt="" />', $message);
Use $1 reference - it is a link to a first group that PHP matched through preg_replace
You just need to use $n in your replacement to reference to a certain matching group (n is a number).
Since we pulled out the big guns:
Let's use preg_quote() to escape regex reserved characters in your array
PHP has a great set of function to juggle with arrays, let's use implode() instead of that ugly loop
From the comments, I realised that you need to add word boundaries \b to prevent false matches like yeah being replaced to ye<img...>. See this demo
Code:
$message = 'foo qh bar';
$arr = array('ah', 'kh', 'qh', '3c', '2c');
$escaped_arr = array_map(function($v){
return preg_quote($v, '#');
}, $arr); // Anonymous function requires PHP 5.3+
$message = preg_replace('#\b('.implode('|', $escaped_arr).')\b#', '<img src="$1.png" class="card" alt="" />', $message);
echo $message;
Online demo
You don't need that for loop. Here's a slightly improved version with the correct regex.
$arr = array('ah', 'kh', 'qh', ..., '3c', '2c');
$message = preg_replace('/('. implode('|'. $regex) .')/is', '<img src="$1.png" class="card" alt="" />', $message);
You should improve your 'markers' indicating the playing cards, by adding a special character (like # in the following example) to them. This will protect you from inadvertently changing other text passages:
$arr = array('ah', 'kh', 'qh', 'ac', '3c', '2c');
$txt = 'This is a line with cards #ah and #qh but with a potential head-ache.';
$rx = '##('.join('|',$arr).')#';
echo preg_replace($rx,"<img src=$1.jpg>",$txt);

Categories