Reputation: 95
I'm trying to change the src attribute of an iframe from http to https. For example, my string is:
<p>Some random text <iframe src="http://some-random-link.com" width="425" height="350" frameborder="0"></iframe></p>
What I need is to change it to
<p>Some random text <iframe src="https://some-random-link.com" width="425" height="350" frameborder="0" ></iframe></p>
By far, I've been trying with preg_replace but no results:
$res = preg_replace( '/<iframe\s+.*?\s+src="http(.*?)".*?<\/iframe>/', '<iframe\s+.*?\s+src="https$1".</iframe>', $string);
Thank you
Upvotes: 3
Views: 3360
Reputation: 47904
Why should you use a legitimate DOM parser instead of regex -- even for such a minor string manipulation?
Because regex is not "DOM-aware" -- it will treat a substring that isn't a tag as if it was a tag just because it resembles a tag.
Because your input may change slightly with or without your consent.
Because your required string manipulation may grow in complexity as your application matures.
Because using dedicated tools for the tasks they were designed to tackle, makes you appear to be a careful, considered, and professional IT craftsman/craftswoman.
First, a loop of iframe nodes using only DOM parser followed by a url parser, then substr_replace()
to inject the 's' without removing any of the original characters.
Code: (Demo)
$html = <<<HTML
<p>Some random text <iframe src="http://some-random-link.com" width="425" height="350" frameborder="0"></iframe></p>
HTML;
$dom = new DOMDocument;
$dom->loadHTML($html, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
foreach ($dom->getElementsByTagName('iframe') as $iframe) {
$src = $iframe->getAttribute('src');
if (parse_url($src, PHP_URL_SCHEME) === 'http') {
$iframe->setAttribute('src', substr_replace($src, 's', 4, 0));
}
}
echo $dom->saveHTML();
Alternatively, you can target the qualifying src
attributes with XPath.
Code: (Demo)
$html = <<<HTML
<p>Some random text <iframe src="http://some-random-link.com" width="425" height="350" frameborder="0"></iframe>
<iframe src="https://cant-touch-this.com" width="425" height="350" frameborder="0"></iframe>
</p>
HTML;
$dom = new DOMDocument;
$dom->loadHTML($html, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
$xpath = new DOMXPath($dom);
foreach ($xpath->query("//iframe[starts-with(@src, 'http') and not(starts-with(@src, 'https'))]/@src") as $src) {
$src->nodeValue = substr_replace($src->nodeValue, 's', 4, 0);
}
echo $dom->saveHTML();
Not only will these techniques be more reliable than regex, the syntax to these parsers is far more readable by humans and will make your script much easier to manage over time.
Upvotes: 1
Reputation: 5543
You can try this regex :
/(<iframe.+?src=".*?)(?=:)/
Live demo here
Sample code in php:
$re = '/(<iframe.+?src=".*?)(?=:)/';
$str = '<p>Some random text <iframe src="http://some-random-link.com" width="425" height="350" frameborder="0"></iframe></p>';
$subst = '\\1s';
$result = preg_replace($re, $subst, $str);
echo $result;
// <p>Some random text <iframe src="https://some-random-link.com" width="425" height="350" frameborder="0"></iframe></p>
Upvotes: 3
Reputation: 9396
Try the following REGEX instead(DEMO):
/<iframe.*?s*src="http(.*?)".*?<\/iframe>/
But beware, You CAN NOT parse HTML with REGEX properly. Please, use some XML parser instead.
Also, it seems you only want to change http
to https
. So for that try the following instead:
if(strpos($string, 'https') === false)
{
$string = str_replace("http", "https", $string);
}
Upvotes: 4