PHP - Wrap multiple instances with preg_replace - php

I have a string like this:
'<img src="image1.jpg"><img src="image2.jpg"><img src="image3.jpg">
<img src="image4.jpg"><img src="image5.jpg">'
I'd like to come to:
'<div class="slide"><img src="image1.jpg"><img src="image2.jpg"></div>
<div class="slide"><img src="image2.jpg"><img src="image3.jpg"></div>
<div class="slide"><img src="image3.jpg"></div>'
So basically I'd like to apply a preg_replace to wrap every 2 elements in a DIV.
I searched the forum and found some tips that I tried:
$pattern = '/(<img[^>]*class=\"([^>]*?)\"[^>]*>)+/i';
$replacement = '<div class="slide">$1</div>';
$content = preg_replace($pattern, $replacement, $content);
and
$pattern = '/(<img[^>]*class=\"([^>]*?)\"[^>]*>){2,}/i';
$replacement = '<div class="slide">$1</div>';
$content = preg_replace($pattern, $replacement, $content);
But it doesn't work...
Any idea, guys?
Thank you!

Use DomDocumen object to do it:
$str = '<img src="image1.jpg"><img src="image2.jpg"><img src="image3.jpg">
<img src="image4.jpg"><img src="image5.jpg">';
$dom = new DomDocument;
$dom->loadHTML($str);
$imgs = $dom->getElementsByTagName('img');
$i = $imgs->length;
$cur = 0;
$res = new DomDocument;
while ($i >= 2) {
$div = $res->createElement('div');
$div->setAttribute("class","slide");
$res->appendChild($div);
$div->appendChild($res->importNode($imgs->item($cur++)));
$div->appendChild($res->importNode($imgs->item($cur++)));
$i -= 2;
}
if($i) $res->appendChild($res->importNode($imgs->item($cur++)));
echo $res->saveHTML();
// <div class="slide"><img src="image1.jpg"><img src="image2.jpg"></div><div class="slide"><img src="image3.jpg"><img src="image4.jpg"></div><img src="image5.jpg">

Here is working example:
<?php
$content = '<img src="image1.jpg"><img src="image2.jpg">
<img src="image3.jpg"><img src="image4.jpg">
<img src="image5.jpg">';
$pattern = '/((<img[^>]*src=\"([^>]*?)\"[^>]*>\s*){2,2})/i';
$replacement = '<div class="slide">$1</div>';
$content = preg_replace($pattern, $replacement, $content);
echo $content;
It is your second example, but with 4 fixes:
class -> src
added block () to catch 2 items
fixed quantity {2,} -> {2,2} (change it to {1,2} if you want to catch last one img tag)
\s* added to catch spaces and line breaks between img tags

Related

Wordpress: Convert img tag to div background img

I'd like to convert my wordpress post img tags in my post to div background images. I currently have a function setup to add a class to the parent paragraph tag. Any idea how to edit the preg replace to change the img tag to a div and set the style="background-image: url("{img_src}");" with the img src?
My current function is:
function give_attachments_class($content){
$classes = 'class="img_wrap"';
$firstH2 = 'class="first_h2"';
$img_match = preg_match("/(<p.*?)(.*?><img)/", $content, $img_array);
$youtube_match =preg_match("/(<p><span)+[ ]+(class=)+['\"]embed-youtube/", $content, $output_array);
if(!empty($img_match))
{
$content = preg_replace('/(<p.*?)(.*?><img)/', '$1 ' . $classes . '$2', $content);
}
if(!empty($youtube_match))
{
$content = preg_replace("/(<p><span)+[ ]+(class=)+['\"]embed-youtube/", "<p class=\"img_wrap\"><span class='embed-youtube", $content);
}
$content = preg_replace('/<div .*?class="(.*?video-container.*?)">(.*?)<\/div>/','<p class="img_wrap"><span class="embed-youtube">$2</span></p>',$content);
return $content;
}
Try this for your img tags. Dump you db before just in case.
$pattern = '/img([^>]*?>)/i';
$replacement = 'div$1</div>';
echo preg_replace($pattern, $replacement, $content);
Update 2
This will get rid of the style attributes on your img tags, then builds new style tags with the required css, while replacing the src tags, then turns the img tags to divs. It also keeps other attributes like title type whatever.
$content = "<img type=\"asd\" style=\"color:red\" src=\"qwe\" class=\"asd\" > lorem
ipsum <img type=\"asd\" style=\"color:red\" src=\"qwe\" class=\"asd\" >";
$pattern = '/style=".*?"/';
$replacement = "";
$result = preg_replace($pattern, $replacement, $content);
$pattern = '/src="(.*?)"/';
$replacement = "style=\"background-image:url($1);\"";
$result = preg_replace($pattern, $replacement, $result);
$pattern = '/img((.*?)(style=".*?")((.*?)(>|\/>)))/';
$replacement = 'div$2$3'.'$5></div>';
echo preg_replace($pattern, $replacement, $result);

How to remove part of a string, that's wrapped in <b></b>, with php? [duplicate]

This question already has an answer here:
DOM php delete all tags by tag name
(1 answer)
Closed 7 years ago.
So I have a text being pulled from db:
<b>Object title</b>
<br />
<p>Object description</p>
and I need to remove <b>Object title</b>, I tried using substr, but didn't quite come up with the correct way of putting it together. Can you please show me how I could do that?
Edit
Please note: I need to remove only the first <b></b> element, every other bold part of that string should stay the way it is.
u shoud use preg_match for this problem.
$text = "<b>Object title</b><br /><p>Object description</p>";
if (!preg_match("/<b>.*<\/b>/",$text,$m)) {
str_replace($m[0],"",$text);
}
this should work for u.
if u want remove all u can run a a loop on $m.
This can be obtained without the use of regex as well.
We are using simple PHP string functions here:
Try this:
<?php
function removeTags($subject, $replaceStr){
$strlength = strlen($replaceStr);
$subject = strstr($subject, $replaceStr, true) . substr(strstr($subject, $replaceStr), 0 + $strlength);
return $subject;
}
$str = '<b>Object title</b><b>Object title</b><br /><p>Object description</p><b>Object title</b>';
$brOpenRemoved = removeTags($str, '<b>');
$brCloseRemoved = removeTags($brOpenRemoved, '</b>');
echo $brCloseRemoved; // final output
?>
The function removeTags removes the string provided to it. We have provided tags here.
It only removes first occurrence because we are using functions like strstr() which only work on first occurence of the string.
EDIT
We can use below function to prevent calling the same function again and again
<?php
function removeFirstOccurence($subject, $replaceTag){
$replaceStrings = ['<'.$replaceTag.'>', '</'.$replaceTag.'>'];
foreach($replaceStrings as $replaceStr){
$strlength = strlen($replaceStr);
$subject = strstr($subject, $replaceStr, true) . substr(strstr($subject, $replaceStr), 0 + $strlength);
}
return $subject;
}
$str = '<b>Object title</b><b>Object title</b><br /><p>Object description</p><b>Object title</b>';
$brRemoved = removeFirstOccurence($str, 'b');
echo $brRemoved; // final output
?>
If you are sure that there is your pattern in the text:
//remove first <b> tag
$text = '<b>foo</b>...';
$pos = strpos($text,'<b>');
if ($pos !== false) {
$newtext = substr_replace($text,'',$pos,strlen('<b>'));
}
//remove first </b> tag
$pos = strpos($text,'</b>');
if ($pos !== false) {
$newtext = substr_replace($newtext,'',$pos,strlen('</b>'));
}
You can use $limit to the maximum possible replacements for each pattern in preg_replace
$yourString =
"<b>Object title</b>
<br />
<p>Object description</p>";
$limit = 1;
$pattern = "/<b>(.*)<\/b>/";
$replace = "";
$newString = preg_replace($pattern, $replace, $yourString, $limit);
echo $newString;
output:
<br />
<p>Object description</p>
If you use (.*) you can also delete <b> and </b> tags and just stay with the content:
$limit = 1;
$pattern = "/<b>(.*)<\/b>/";
$replace = "$1";
$newString = preg_replace($pattern, $replace, $yourString, $limit);
echo $newString;
output:
Object title
<br />
<p>Object description</p>
Or keep only tags without content:
$limit = 1;
$pattern = "/<b>(.*)<\/b>/";
$replace = "<b></b>";
$newString = preg_replace($pattern, $replace, $yourString, $limit);
echo $newString;
output:
<b></b>
<br />
<p>Object description</p>

Preg_replace replace dashes with spaces between tags

I have a HTML code and would like to replace only the dashes with spaces but only between specific tags.
function getTextBetweenTags($string, $tagname) {
$pattern = "/<$tagname ?.*>(\d*)[-*](\d*)<\/$tagname>/";
$replace = " ";
$string = preg_replace($pattern, $replace, $string);
}
CODE EXAMPLE:
<div class="xxx">
start
World
Fantastic-yyy-zz
peter-hey
</div>
RESULT: Although 'peter hey' is without dashes it's more important the Tag's values.
<div class="xxx">
start
World
Fantastic yyy zz
peter-hey
</div>
You DO NOT need regular expressions for this task:
$contents = '<div class="xxx">
start
World
Fantastic-yyy-zz
peter-hey
</div>';
$doc = new DOMDocument();
$doc->loadXML($contents);
$tagName = 'a';
$tags = $doc->getElementsByTagName($tagName);
foreach ($tags as $tag) {
$newValue = str_replace('-', ' ', $tag->nodeValue);
$tag->nodeValue = $newValue;
}
echo $doc->saveHTML();
Demo: http://ideone.com/rI6k8b
#zerkms thank you for your help and patience, tried almost exactly as you told but it shows a warning and doesn't make a change.
Warning: DOMDocument::loadXML(): Extra content at the end of the document in Entity
CODE:
function process(&$vars) {
$theme = get_theme();
if ($vars['elts']['#xxx'] == 'main') {
$vars['bread'] = $theme->page['bread'];
/*add code*/
$doc = new DOMDocument();
$doc->loadXML($vars['bread']);
$tagName = 'a';
$tags = $doc->getElementsByTagName($tagName);
foreach ($tags as $tag) {
$newValue = str_replace('-', ' ', $tag->nodeValue);
$tag->nodeValue = $newValue;
}
echo $doc->saveHTML();
/*end add code*/
}
}
#zerkms, I give you the answer as valid as you really gave a correct answer. I'm also amazed to say that I found some interesting answers:
CODE TO FIND INFO
$tagname = 'a';
$pattern = "/<$tagname ?.*>(.*)\-+(.*)<\/$tagname>/";
$matches = "";
preg_match($pattern, $contents, $matches);
CODE TO CHANGE : As I only have a piece of code, I really don't need to check the tag is 'a'.
$pattern = "/>(.*)\-+(.*)\-+(.*)</";
$replace = ">$1 $2 $3<";
$res = preg_replace($pattern, $replace, $contents);
//$contents is my string with the code.
Hope it really helps someone.

PHP - replace <img> tags and return src

Mission is to replace all <img> tags in given string with <div> tags and src property as inner text.
In search for the answer I found similar question
<?php
$content = "this is something with an <img src=\"test.png\"/> in it.";
$content = preg_replace("/<img[^>]+\>/i", "(image) ", $content);
echo $content;
?>
result:
this is something with an (image) in it.
Question: How to upgrade script ant get this result:
this is something with an <div>test.png</div> in it.
This is the kind of problem that PHP's DOMDocument class excels at:
$dom = new DOMDocument();
$dom->loadHTML($content);
foreach ($dom->getElementsByTagName('img') as $img) {
// put your replacement code here
}
$content = $dom->saveHTML();
$content = "this is something with an <img src=\"test.png\"/> in it.";
$content = preg_replace('/(<)([img])(\w+)([^>]*>)/', '<div>$1</div>', $content);
echo $content;
<?php
$strings = 'awdaw <img src="http://ua1.us/media/media.jpg" alt="Image" width="100" height="100"> aw <img src="http://ua1.us/media/media1awdwa.jpg"> wawadwad';
preg_match_all('/<img[^>]+>/i', $strings, $images);
foreach ($images[0] as $image) {
preg_match('/src="([^"]+)/i', $image, $replacements);
$replacement = isset($replacements[1]) ? $replacements[1] : (isset($replacements[0]) ? $replacements[0] : "image");
$strings = str_replace($image, $replacement, $strings);
}
echo $strings;

Convert clickable anchor tags to plain text in html document

I am trying to match <a> tags within my content and replace them with the link text followed by the url in square brackets for a print-version.
The following example works if there is only the "href". If the <a> contains another attribute, it matches too much and doesn't return the desired result.
How can I match the URL and the link text and that's it?
Here is my code:
<?php
$content = 'This is a text link';
$result = preg_replace('/<a href="(http:\/\/[A-Za-z0-9\\.:\/]{1,})">([\\s\\S]*?)<\/a>/',
'<strong>\\2</strong> [\\1]', $content);
echo $result;
?>
Desired result:
<strong>This is a text link </strong> [http://www.website.com]
You should be using DOM to parse HTML, not regular expressions...
Edit: Updated code to do simple regex parsing on the href attribute value.
Edit #2: Made the loop regressive so it can handle multiple replacements.
$content = '
<p>This is a text link</p>
bah
I wont change
';
$dom = new DOMDocument();
$dom->loadHTML($content);
$anchors = $dom->getElementsByTagName('a');
$len = $anchors->length;
if ( $len > 0 ) {
$i = $len-1;
while ( $i > -1 ) {
$anchor = $anchors->item( $i );
if ( $anchor->hasAttribute('href') ) {
$href = $anchor->getAttribute('href');
$regex = '/^http/';
if ( !preg_match ( $regex, $href ) ) {
$i--;
continue;
}
$text = $anchor->nodeValue;
$textNode = $dom->createTextNode( $text );
$strong = $dom->createElement('strong');
$strong->appendChild( $textNode );
$anchor->parentNode->replaceChild( $strong, $anchor );
}
$i--;
}
}
echo $dom->saveHTML();
?>
You can make the match ungreedy using ?.
You should also take into account there may be attributes before the href attribute.
$result = preg_replace('/<a [^>]*?href="(http:\/\/[A-Za-z0-9\\.:\/]+?)">([\\s\\S]*?)<\/a>/',
'<strong>\\2</strong> [\\1]', $content);

Categories