BBCODE IMG TAG variations with REGEX - php

I need to convert BBCODE IMG TAG to HTML.
The problem is: the IMG TAG has multiple variations.
[img]img_patch[/img]
[img=200x150]img_patch[/img]
[img width=200 height=150]img_patch[/img]
[img=width=200xheight=150]img_patch[/img]
[img width=200]img_patch[/img]
This regex below cover the First one and the Second one.
'#\[img](.+)\[/img]#Usi',
'#\[img=?(\d+)?x?(\d+)?\](.*?)\[/img\]#Usi',
I need help with the other variations or turning all the variations in an unique REGEX.
I realy apreciate your help!

This should cover all cases:
<?php
$data = <<<DATA
[img]img_patch[/img]
[img=200x150]img_patch[/img]
[img width=200 height=150]img_patch[/img]
[img=width=200xheight=150]img_patch[/img]
[img width=200]img_patch[/img]
DATA;
$regex = '~
(?P<tag>\[img[^][]*\])
(?P<src>.+?)
\[/img]
~x';
$inner = '~\b(?P<key>width|height)?=(?P<value>[^\s\]]+)~';
$values = '~\d+~';
$data = preg_replace_callback($regex,
function($match) use($inner, $values) {
$attr = [];
preg_match_all($inner, $match['tag'], $attributes, PREG_SET_ORDER);
foreach($attributes as $attribute) {
if (!empty($attribute["key"])) $attr[$attribute["key"]] = $attribute["value"];
else {
preg_match_all($values, $attribute["value"], $width_height);
list($attr["width"], $attr["height"]) = array($width_height[0][0], $width_height[0][1]);
}
}
// do the actual replacement here
$attr["src"] = $match["src"];
$ret = "<img";
foreach ($attr as $key => $value) $ret .= " $key='$value'";
$ret .= '>';
return $ret;
},
$data);
echo $data;
?>
And yields
<img src='img_patch'>
<img height='150' width='200' src='img_patch'>
<img width='200' height='150' src='img_patch'>
<img height='150' width='200' src='img_patch'>
<img width='200' src='img_patch'>
The code uses a multi-step-approach: first matching all the tags, then analyzing the attributes. In the end, the new string is formed.
See a demo on ideone.com.
Note: As opposed to your (nickname) son, now you actually do know something, don't you?

Hey Jan I really thank you for your help! Yes, I don't know everything but I do know something. Actually I have created the following REGEX and works fine and covers all IMG TAGs:
'#\[img=(.+)\]#Usi',
'#\[img=+(\d+)x+(\d+)\](.+)\[/img\]#Usi',
'#\[img[\s|=]+[width=]+([0-9]+)?[\s|x]+[height=]+([0-9]+)\](.+)\[/img\]#Usi',
'#\[img[\s]+[width=]+([0-9]+)\](.+)\[/img\]#Usi',
I hope this post may help others on their own projects!

Related

How to preg_match_all to get the text inside the tags "<h3>" and "<h3> <a/> </h3>"

Hello I am currently creating an automatic table of contents my wordpress web. My reference from
https://webdeasy.de/en/wordpress-table-of-contents-without-plugin/
Problem :
Everything goes well unless in the <h3> tag has an <a> tag link. It make $names result missing.
I see problems because of this regex section
preg_match_all("/<h[3,4](?:\sid=\"(.*)\")?(?:.*)?>(.*)<\/h[3,4]>/", $content, $matches);
// get text under <h3> or <h4> tag.
$names = $matches[2];
I have tried modifying the regex (I don't really understand this)
preg_match_all (/ <h [3,4] (?: \ sid = \ "(. *) \")? (?:. *)?> <a (. *)> (. *) <\ / a> <\ / h [3,4]> /", $content, $matches)
// get text under <a> tag.
$names = $matches[4];
The code above work for to find the text that is in the <h3> <a> a text </a> <h3> tag, but the h3 tag which doesn't contain the <a> tag is a problem.
My Question :
How combine code above?
My expectation is if when the first code result does not appear then it is execute the second code as a result.
Or maybe there is a better solution? Thank you.
Here's a way that will remove any tags inside of header tags
$html = <<<EOT
<h3>Here's an alternative solution</h3> to using regex. <h3>It may <a name='#thing'>not</a></h3> be the most elegant solution, but it works
EOT;
preg_match_all('#<h(.*?)>(.*?)<\/h(.*?)>#si', $html, $matches);
foreach ($matches[0] as $num=>$blah) {
$look_for = preg_quote($matches[0][$num],"/");
$tag = str_replace("<","",explode(">",$matches[0][$num])[0]);
$replace_with = "<$tag>" . strip_tags($matches[2][$num]) . "</$tag>";
$html = preg_replace("/$look_for/", $replace_with,$html,1);
}
echo "<pre>$html</pre>";
The answer #kinglish is the base of this solution, thank you very much. I slightly modify and simplify it according to my question article link. This code worked for me:
preg_match_all('#(\<h[3-4])\sid=\"(.*?)\"?\>(.*?)(<\/h[3-4]>)#si',$content, $matches);
$tags = $matches[0];
$ids = $matches[2];
$raw_names = $matches[3];
/* Clean $rawnames from other html tags */
$clean_names= array_map(function($v){
return trim(strip_tags($v));
}, $raw_names);
$names = $clean_names;

Error replace image tag to image src

$content = 'This fairy tale-like place is based on a story of two lovers who ran away to escape their enemies.
<img src="blisshouse-1.jpg"> <img src="blisshouse-2.jpg">';
preg_match_all('%<img.*?src=["\'](.*?)["\'].*?/>%i', $content, $matches);
if(count($matches) > 0) {
foreach ($matches as $matche) {
$content = preg_replace('%<img.*?src=["\'](.*?)["\'].*?/>%i', $matche[1], $content);
}
}
echo $content;
Result is:
This fairy tale-like place is based on a story of two lovers who ran away to escape their enemies.
blisshouse-1.jpg blisshouse-1.jpg
Error can't replace <img src="blisshouse-2.jpg"> to blisshouse-2.jpg. How to fix it
As #Mario suggested - just use preg_replace
Also, I added a /? because the img tags didn't have slashes.
$content = 'This fairy tale-like place is based on a story of two lovers who ran away to escape their enemies.
<img src="blisshouse-1.jpg"> <img src="blisshouse-2.jpg">';
$content = preg_replace('%<img.*?src=["\'](.*?)["\'].*?/?>%i', '$1', $content);
echo $content;

Deleting img tag from string

I've got a string, $content, that contains:
<p>Some random text <img class="alignnone" src="logo.png" alt="" width="1920" height="648"></p>
Now I want to delete the image tag:
<img class="alignnone" src="logo.png" alt="" width="1920" height="648">
I tried strip_tags but that isn't working anymore.
$content = strip_tags($content, '<img></img>');
Here is a complete working example.
<?php
$content = "<p>Some random text <img class=\"alignnone\" src=\"logo.png\" alt=\"\" width=\"1920\" height=\"648\"></p>";
echo strip_tags($content,"<p>");
?>
If <p></p> is the only other tag you'll have you can use strip_tags like this:
$content = strip_tags($content, '<p></p>');
If there may be other tags you want to keep, just add them to the second argument of strip_tags
You can also use a combination of string functions to achieve this:
$count = substr_count($c, '<img ');
while($count >= 1){
$i = strpos($c, '<img ');
$j = strpos($c, '>',$i)+1;
$c = substr($c, 0,$i) . substr($c,$j);
$count--;
}
echo $c;
This also takes care of multiple <img> tags
You could search for the img-Tags with the strpos()-function:
http://www.w3schools.com/php/func_string_strpos.asp
Once you know the start- and ending-position inside the string you can access the parts you need with the substr()-function:
http://php.net/manual/de/function.substr.php
In your example:
$left = strpos($content,'<img');
//$left should now be "20"
//to find the closing >-tag you need the string starting from <img... so you assign that to $rest:
$rest = substr($content,(strlen($content)-$left+1)*(-1));
$right = strpos($rest,">")+$left;
//now you know where the img ends so you can get the string surrounding it with:
$surr = substr($content,0,$left).substr($content,(strlen($content)-$right)*(-1));
Edit: Tested, will work for deleting the first img-Tag

PHP Preg_match Matching a class and getting content after

$str = '<div class="rss"><img src="http://www.wired.com/images_blogs/gadgetlab/2013/10/1125_hbogo_660-660x436.jpg" alt="You Can Now Get HBO GO Without Paying for Other Channels">
</div>Fans of';
I'm trying to get hold of the text after the <div class="rss"></div> but each expression I use doesn't seem to work.
matching .rss
if(preg_match('/^(<div class=\"rss\">[\S\s]+?</div>([\S\s]*)$/i', $item_content, $matches)) {
Could someone please help with this expression?
Originally I had this expression to match an image tag instead of a div and this worked fine by using
if(preg_match('/^(<img[\S\s]+?>)([\S\s]*)$/i', $item_content, $matches)) {
I didn't go deeply for the regex but yours work well with just solving some syntax problems.
It should be:
^<div class=\"rss\">[\S\s]+?<\/div>([\S\s]*)$/i
Live demo
This may help:
<?php
$item_content = '<div class="rss"><img src="http://www.wired.com/images_blogs/gadgetlab/2013/10/1125_hbogo_660-660x436.jpg" alt="You Can Now Get HBO GO Without Paying for Other Channels">
</div>Fans of';
if(preg_match('/^(<div class=\"rss\">[\S\s]+?<\/div>)([\S\s]*)$/i', $item_content, $matches)) {
$div = $matches[1];
$text = $matches[2];
echo "<textarea style=\"width: 600px; height: 300px;\">";
echo $div . "\n";
echo $text . "\n";
echo "</textarea>";
}
?>

Using php preg to find url and replace it with a second url

I've got a large number of webpages stored in an MySQL database.
Most of these pages contain at least one (and occasionally two) entries like this...
<a href="http://first-url-which-always-ends-with-a-slash/">
<img src="http://second-different-url-which-always-ends-with.jpg" />
</a>
I'd like to just set up a little php loop to go through all the entires replacing the first url with a copy of the second url for that entry.
How can I use preg to:
find the second url from the image tag
replace the first url in the a tag, with a copy of the second url
Is this possible?
see this url
PHP preg match / replace?
see also:- http://php.net/manual/en/function.preg-replace.php
$qp = qp($html);
foreach ($qp->find("img") as $img) {
$img->attr("title", $img->attr("alt"));
}
print $qp->writeHTML();
Though it might be feasible in this simple case to resort to an regex:
preg_replace('#(<img\s[^>]*)(\balt=)("[^"]+")#', '$1$2$3 title=$3', $h);
(It would make more sense to use preg_replace_callback to ensure no title= attribute is present yet.)
You can do following :
$dom = new DOMDocument('1.0', 'UTF-8');
$dom->formatOutput = true;
$source = "<a href=\"http://first-url-which-always-ends-with-a-slash/\">
<img src=\"http://second-different-url-which-always-ends-with.jpg\" />
</a>";
$dom->loadHTML($source);
$tags = $dom->getElementsByTagName('a');
foreach ($tags as $tag) {
$atag = $tag->getAttribute('href');
$imgTag = $dom->getElementsByTagName('img');
foreach ($imgTag as $img) {
$img->setAttribute('src', $atag);
echo $img->getAttribute('src');
}
}
Thanks for the suggestions i can see how they are better than using Preg.
Even so i finally solved my own question like this...
$result = mysql_query($select);
while ($frow = mysql_fetch_array($result)) {
$page_content = $frow['page_content'];
preg_match("#<img\s+src\s*=\s*([\"']+http://[^\"']*\.jpg[\"']+)#i", $page_content, $matches1);
print_r($matches1);
$imageURL = $matches1[1] ;
preg_match("#<a\s+(?:[^\"'>]+|\"[^\"]*\"|'[^']*')*href\s*=\s(\"http://[^\"]+/\"|'http://[^']+/')#i", $page_content, $matches2);
print_r( $matches2 );
$linkURL = $matches2[1] ;
$finalpage=str_replace($linkURL, $imageURL, $page_content) ;
}

Categories