VANKO
VANKO

Reputation: 53

PHP/Regex. How to replace all percent (%) chars in url after domain?

I have a problem, i was trying to make a regex for preg_replace to replace all percent (%) chars by "_" char in url after domain name (in domain path).

Example:

This is c%ontent with 1 url her%e http://example.com/this%is%image.jpg
and 1 url here http://anotherexample.com/t%his%is%image2.jpg

Result:

This is c%ontent with 1 url her%e http://example.com/this_is_image.jpg
and 1 url here http://anotherexample.com/t_his_is_image2.jpg

And my question: How to do that using preg_replace ?

All what i have is regex for selecting domain in img tag:

/<img [^>]*src="([^"]+example\.com\/[^"]+)"[^>]*>/

Upvotes: 2

Views: 858

Answers (4)

vsnyc
vsnyc

Reputation: 2257

This is not as elegant as @ins0's answer but I came up with yet another solution, I don't normally code in php, so this may not be the most optimal. Please drop a comment if it can be improved.

$str3 = "This is c%ontent with 1 url her%e http://example.com/this%is%image.jpg and 1 url here http://anotherexample.com/t%his%is%image2.jpg ";
$regex = "(http\\S+(\\s|$))";
$unmatched = preg_split($regex, $str3);
preg_match_all($regex, $str3, $matches);
$substituted = (str_replace("%", "_", $matches[0]));
$result = "";
foreach($substituted as $key=>$value) {
    $result .= $unmatched[$key];
    $result .= $substituted[$key];
}  
print $result; # for testing

Upvotes: 1

ins0
ins0

Reputation: 3928

If you dealing with regex replacements i would suggest preg_replace_callback

http://php.net/manual/en/function.preg-replace-callback.php

Please keep in mind that replaceing % in urls can be dangerous as an url can have some valid % characters like http://foo.bar/here%20/index.html where the %20 is an whitespace!

Example

$haystack = 'This is c%ontent with 1 url her%e http://example.com/this%is%image.jpg 
and 1 url here http://anotherexample.com/t%his%is%image2.jpg';

// please use your fav url regex here
$urlRegex = '#\bhttps?://[^\s()<>]+(?:\([\w\d]+\)|([^[:punct:]\s]|/))#';

$haystack = preg_replace_callback($urlRegex, function($url){
    return str_replace('%', '_', $url[0]);
}, $haystack);

Upvotes: 4

billyonecan
billyonecan

Reputation: 20260

You could match the URLs in the string with a simple regular expression:

// $subject is the string    
preg_match_all('/http:\/\/[^\s]+/', $subject, $matches);

Then loop over the matches, replace the % with _ in the URL, and replace that in the original $subject:

foreach ($matches as $match) {
    $search = $match;
    $replace = str_replace('%', '_', $match);
    $subject = str_replace($search, $replace, $subject);
}

Upvotes: 2

You Old Fool
You Old Fool

Reputation: 22950

How about using dirname(), basename() and str_replace() like this:

$haystack = 'This is c%ontent with 1 url her%e http://example.com/this%is%image.jpg';
$result = dirname($haystack) . '/' . str_replace('%','_',basename($haystack));
echo $result;

RESULT:

This is c%ontent with 1 url her%e http://example.com/this_is_image.jpg

This would be much more efficient than using preg_replace() and a regex.

UPDATE:

As ins0 points out the above answer depends on the string containing only one url which is at the end. Not very flexible. Here's another idea based on what I posted above:

$haystack = 'This is c%ontent with 1 url her%e http://example.com/this%is%image.jpg 
and 1 url here http://anotherexample.com/t%his%is%image2.jpg';

$parts = explode(' ',$haystack);
foreach ($parts as &$part) {
    if (strpos($part,'http://') !== false || strpos($part,'https://') !== false) {
        $part = dirname($part) . '/'. str_replace('%','_',basename($part));
    }
}
$haystack = implode(' ',$parts);
echo $haystack;

RESULT:

This is c%ontent with 1 url her%e http://example.com/this_is_image.jpg
and 1 url here http://anotherexample.com/t_his_is_image2.jpg

Upvotes: 1

Related Questions