Get parts of strings with PHP - php

i'm trying to substract parts of a string in a variable with php, refeering in a specific text condition: class="image-GET_THIS_NUMBER" and storing it into an array. The variable is something like:
$content = '<p>
<img src="#" alt="" class="image-1">
<img src="#" alt="" class="image-96">
<img src="#" alt="" class="image-12231">
<img src="#" alt="" class="image-444312">
</p>';
And i need get this:
$images = array(1, 96, 12231, 444312);
I don't really know if it's possible to do. Hope you can help me.

You can do it with Regex.
Here you are
$content = '<p>
<img src="#" alt="" class="image-1">
<img src="#" alt="" class="image-96">
<img src="#" alt="" class="image-12231">
<img src="#" alt="" class="image-444312">
</p>';
preg_match_all("/class=\"image-([0-9]+)\"/is", $content, $matches);
$images = $matches[1];

To find all matches in your html string, a regex search will be the ticket.
preg_match_all('/class="image-(\d+)/', $content, $matches);

Related

retrieve all images path from string with PHP

How do I get all images path from a string?
Note I just want the path containing the word "media".
For example given this string (part of the DOM)
<div class="my-class">
<img src="http://my-website.com/cache/media/2017/10/img67.jpeg" class="" alt="test" width="120" height="100">
<img src="http://my-website.com/cache/2017/10/img68.png" class="" alt="test" width="120" height="100">
<img src="http://my-website.com/cache/media/2017/10/img69.jpg" class="" alt="test" width="120" height="100">
<h2 class="uk-margin-top-remove">About us</h2>
</div>
I want an array containing a similar result:
array(
[0] => "http://my-website.com/cache/media/2017/10/img67.png"
[1] => "http://my-website.com/cache/media/2017/10/img69.png"
);
I don't want the second img because src attribute doesn't contain the word "media".
You could use preg_match_all() to get URLs but it is even better to use a DOM reader.
$str = '<div class="my-class">
<img src="http://my-website.com/cache/media/2017/10/img67.jpeg" class="" alt="test" width="120" height="100">
<img src="http://my-website.com/cache/2017/10/img68.png" class="" alt="test" width="120" height="100">
<img src="http://my-website.com/cache/media/2017/10/img69.jpg" class="" alt="test" width="120" height="100">
<h2 class="uk-margin-top-remove">About us</h2>
</div>' ;
$matches = [] ;
preg_match_all('~(http\://my-website\.com/cache/media/(.*?))"~i', $str, $matches) ;
var_dump($matches[1]);
Will returns :
array(2) {
[0]=>
string(52) "http://my-website.com/cache/media/2017/10/img67.jpeg"
[1]=>
string(51) "http://my-website.com/cache/media/2017/10/img69.jpg"
}
Some boilerplate code to get you started:
<?php
$data = <<<DATA
<div class="my-class">
<img src="http://my-website.com/cache/media/2017/10/img67.jpeg" class="" alt="test" width="120" height="100">
<img src="http://my-website.com/cache/2017/10/img68.png" class="" alt="test" width="120" height="100">
<img src="http://my-website.com/cache/media/2017/10/img69.jpg" class="" alt="test" width="120" height="100">
<h2 class="uk-margin-top-remove">About us</h2>
</div>
DATA;
# set up the dom
$dom = new DOMDocument();
$dom->loadHTML($data, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);# | LIBXML_COMPACT | LIBXML_NOENT );
# set up the xpath
$xpath = new DOMXPath($dom);
foreach ($xpath->query("//img[contains(#src, '/media/')]/#src") as $image) {
echo $image->nodeValue . "\n";
}
Which yields
http://my-website.com/cache/media/2017/10/img67.jpeg
http://my-website.com/cache/media/2017/10/img69.jpg
This loads the DOM and uses an xpath query for every image where we'll loop over afterwards.
If for some reasons (why?) you are unable to use a DOM parser, your could use the secondbest option:
<img
(?s:(?!>).)+?
src=(['"])
(?P<src>(?:(?!\1).)+?/media/.*?\1)
And use the src group, see a demo on regex101.com.

What's wrong with my regex to replace src and add class using preg_replace?

I'm a bit lost here. I'm trying to replace src tag with data:image/gif;base64,R0lGODlhAQABAPABAAAAAP///yH5BAAAAAAALAAAAAABAAEAAAICRAEAOw== for lazy loading and add class lazyload so lazysizes could work. But none of that is successful here.
Am I missing something?
public static function filter_lazy_load_gravatar( $html ) {
$html = preg_replace( '/src="(http:\/\/([^\/]+)\/)?([^"]+)"/', 'src="data:image/gif;base64,R0lGODlhAQABAPABAAAAAP///yH5BAAAAAAALAAAAAABAAEAAAICRAEAOw=="', $html);
$html = str_replace( 'srcset=', 'data-srcset=', $html );
$pat = '/class="([^"]*)"/';
$html = preg_replace($pat, 'class="$1 lazyload"', $html);
return $html;
}
Input
<img alt="" src="http://gravatar.com/image.jpg" srcset="http://0.gravatar.com/avatar/0b11f7eec98d2ee78414a4322ea94a01?s=400&d=mm&r=g 2x" class="avatar avatar-200 photo" height="200" width="200">
Expected output
<img alt="" src="data:image/gif;base64,R0lGODlhAQABAPABAAAAAP///yH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==" data-srcset="http://0.gravatar.com/avatar/0b11f7eec98d2ee78414a4322ea94a01?s=400&d=mm&r=g 2x" class="avatar avatar-200 photo lazyload" height="200" width="200">

Adding link tags and rel="lightbox" around images Regex

How can i change this example when i just got the <image> tag and i want to add link tags around them and the rel lightbox attribute as well?
i cant figure it out. I'm just not good with regular expressions at all.
the example
$pattern ="/<a(.*?)href=('|\")(.*?).(bmp|gif|jpeg|jpg|png)('|\")(.*?)>/i";
$replacement = '<a$1href=$2$3.$4$5 rel="lightbox" title="'.$post->post_title.'"$6>';
So in my case i have <img src="...." class="...." alt=".....">
and i need <img src="...." class="...." alt=".....">
How would i change this?
Thanks for help.
It's unclear what you exactly want to do here, but I would utilize DOM for this task instead.
$doc = DOMDocument::loadHTML('
<img src="www.foo.com/1.gif" class="foo" alt="...">
<img src="www.bar.com/1.jpg" class="bar" alt="...">
<img src="example.com/2.jpg" class="example" alt="...">
');
foreach ($doc->getElementsByTagName('img') as $node) {
$link = $node->ownerDocument->createElement('a');
$a = $node->parentNode->insertBefore($link, $node);
$a->setAttribute('href', $node->getAttribute('src'));
$a->setAttribute('rel', 'lightbox');
$a->setAttribute('title', 'some title');
$a->appendChild($node);
}
echo $doc->saveHTML();
Output:
<img src="www.foo.com/1.gif" class="foo" alt="...">
<img src="www.bar.com/1.jpg" class="bar" alt="...">
<img src="example.com/2.jpg" class="example" alt="...">

preg-replace image width, height and style

My image looks like this:
<img alt="" width="146" height="109" src="http://url.to/src.jpg" style="float:left" />
but i can't figure out how to bring it with preg_replace or preg_replace_callback to this:
<img alt="" src="http://url.to/src.jpg" style="width:146;height:109;float:left">
This works with height and width but I can't get the style-element "float:left" added
$html='<img alt="" width="146" height="109" src="http://url.to/src.jpg" style="float:left" />';
$pattern = ('/<img[^>]*width="(\d+)"\s+height="(\d+)">/');
preg_match($pattern, $html, $matches);
$style = "<img style=\"width:".$matches[1]."px; height:".$matches[2]."px;\"";
$html = preg_replace($pattern, $style, $html);
result of this will be
<img alt="" style="width:146;height:109" src="http://url.to/src.jpg" style="float:left">
which didn't work because of the double style element
Try the following regular expression
<?php
$html='<img alt="" width="146" height="109" src="http://placehold.it/140x200" style="float:left" />';
$pattern = '/(<img.*)width="(\d+)" height="(\d+)"(.*style=")(.*)" \/(>)/';
$style = '$1$4width:$2px;height:$3px;$5';
$html = preg_replace($pattern, $style, $html);
echo $html; //view source of page to see the code change
?>
Note the use of brackets '(' ')' to create groups matched that can be later referenced using $1 $2 etc go to regex101.com and try out the regular expression.
Above code will result in following, except the last part, that shouldn't matter but you can modify it further.
<img alt="" src="http://placehold.it/140x200" style="width:146;height:109;float:left" />

Using regex to wrap images in tags

I've been using regex to wrap my images in < a > tags and altering their paths etc.
I know using dom for this is better, having read a lot of threads about wrapping, but I'm unable to understand how to.
This is what I'm using:
$comments = (preg_replace('#(<img.+src=[\'"]/uploads/userdirs/admin)(?:.*?/)(.+?)\.(.+?)([\'"].*?>)#i', '<a class="gallery" rel="'.$pagelink.'" href=/uploads/userdirs/'.$who.'/$2.$3>$1/mcith/mcith_$2.$3$4</a>', $comments));
It successfully wraps each image in the tags I want. But only if the string provided ($comments) has the right markup.
<p><img src="/uploads/userdirs/admin/1160501362291.png" alt="" width="1280" height="960" /></p>
<p><img src="/uploads/userdirs/admin/100_Bullets_68_1280x1024.jpg" alt="" width="1280" height="1024" /></p>
When presented like this, it works. I'm using tinymce so it wraps in < p > when I do a linebreak with enter. But when I don't do that, when I just insert images one after another so the HTML looks like this, it won't:
<p><img src="/uploads/userdirs/admin/1160501362291.png" alt="" width="1280" height="960" /><img src="/uploads/userdirs/admin/100_Bullets_68_1280x1024.jpg" alt="" width="1280" height="1024" /></p>
It will instead wrap those 2 images in the same < a > tag. Making the output look like this:
<p><a class="gallery" rel="test" href="/uploads/userdirs/admin/100_Bullets_68_1280x1024.jpg">
<img src="/uploads/userdirs/admin/1160501362291.png" alt="" width="1280" height="960">
<img src="/uploads/userdirs/admin/mcith/mcith_100_Bullets_68_1280x1024.jpg" alt="" width="1280" height="1024">
</a></p>
Which is wrong. The output I want is this:
<p><a class="gallery" rel="test2" href="/uploads/userdirs/admin/100_Bullets_68_1280x1024.jpg"><img src="/uploads/userdirs/admin/mcith/mcith_100_Bullets_68_1280x1024.jpg" alt="" width="1280" height="1024"></a></p>
<p><a class="gallery" rel="test2" href="/uploads/userdirs/admin/1154686260226.jpg"><img src="/uploads/userdirs/admin/mcith/mcith_1154686260226.jpg" alt="" width="1280" height="800"></a></p>
I've left out a few details, but here's how I would do it using DOMDocument:
$s = <<<EOM
<p><img src="/uploads/userdirs/admin/1160501362291.png" alt="" width="1280" height="960" /></p>
<p><img src="/uploads/userdirs/admin/100_Bullets_68_1280x1024.jpg" alt="" width="1280" height="1024" /></p>
EOM;
$d = new DOMDocument;
$d->loadHTML($s);
foreach ($d->getElementsByTagName('img') as $img) {
$img_src = $img->attributes->getNamedItem('src')->nodeValue;
if (0 === strncasecmp($img_src, '/uploads/userdirs/admin', 23)) {
$a = $d->createElement('a');
$a->setAttribute('class', 'gallery');
$a->setAttribute('rel', 'whatever');
$a->setAttribute('href', '/uploads/userdirs/username/' . $img_src);
// disconnect image tag from parent
$img->parentNode->replaceChild($a, $img);
// and move to anchor
$a->appendChild($img);
}
}
echo $d->saveHTML();
You should change .* in your regular expression with [^>]*. The latter means: any character expect than >. Because regular expression gets as long match as possible. Without this additional condition, this ends up with two <img>'s matched.

Categories