0

I'm replacing plain text with links and I can not do it right.

I tried the preg_replace() function but it seems that it does not solve my problem at all.

$string = 'This is a message with multiple links: http://google.com http://twitter.com http://google.com/qwerty http://facebook.com http://google.com/ytrewq';

preg_match_all('/(^|\s)((http(s)?\:\/\/)?[\w-]+(\.[\w-]+)+[^\s]*[^.,\s])/u', $string, $url);

$links = $url[2];

foreach($links as $link){
    $final_string = str_replace($link, '<a href="'.$link.'">'.$link.'</a>', $string);
}

echo $final_string;

Notice that three links come from the same domain http://google.com, so when replacing the first link, it does so in the others.

The foreach loop I use for functions that I need to execute for each link (I do not write it because it is not important now).

What I hope is to be able to work with all the links separately, and that the links that share domain do not step on each other.

Output I get:

This is a message with multiple links: <a href="http://google.com">http://google.com</a> <a href="http://twitter.com">http://twitter.com</a> <a href="http://google.com">http://google.com</a>/qwerty <a href="http://facebook.com">http://facebook.com</a> <a href="http://google.com">http://google.com</a>/ytrewq

Output I hope:

This is a message with multiple links: <a href="http://google.com">http://google.com</a> <a href="http://twitter.com">http://twitter.com</a> <a href="http://google.com/qwerty">http://google.com/qwerty</a> <a href="http://facebook.com">http://facebook.com</a> <a href="http://google.com/ytrewq">http://google.com/ytrewq</a>
Gabri
  • 121
  • 1
  • 10
  • 1
    Possible duplicate of [Replace URLs in text with HTML links](https://stackoverflow.com/questions/1188129/replace-urls-in-text-with-html-links) – miken32 May 25 '19 at 18:35
  • How about: `preg_match_all('~\b(?:https?://)?\S+/', $string, $url);$links=$url[0];` – Toto May 25 '19 at 18:53
  • @Toto This does not work for me. I want to keep the same regular expression since it is the one I use in general. – Gabri May 25 '19 at 19:01
  • This exactly the same but simplified. – Toto May 25 '19 at 19:05
  • @Toto I receive the following error: `Warning: preg_match_all(): No ending delimiter '~' found in ...` – Gabri May 25 '19 at 19:07
  • Sorry, my bad, change the last `/` into `~`: `preg_match_all('~\b(?:https?://)?\S+~', $string, $url);$links=$url[0];`, using `~` as delimiter allows to not escape `/` and make the regex easier to read. – Toto May 26 '19 at 10:28

2 Answers2

0

You should be using preg_replace_callback() to make it easier.

Try:

$string = 'This is a message with multiple links: ';
$string .= 'http://google.com ';
$string .= 'http://twitter.com ';
$string .= 'http://google.com/qwerty ';
$string .= 'http://facebook.com ';
$string .= 'http://google.com/ytrewq ';

$final_string = preg_replace_callback(
    "/(^|\s)((http(s)?\:\/\/)?[\w-]+(\.[\w-]+)+[^\s]*[^.,\s])/",
    function ( $matches ) {
        $link = trim( $matches[0] );

        return " <a href='$link'>$link</a>";
    },
    $string
);

echo $final_string;

I changed the way you declared $string just to make it easier to read, but it doesn't matter.
Also, note that you don't need any flags in your regex like the u you are making use of. Which, by the way, is incorrect as it should be U, not u.
Hope it helps.

filipecsweb
  • 171
  • 1
  • 10
  • Incredible, it works well for me! I did not know the `preg_replace_callback()` function. Thank you! – Gabri May 25 '19 at 19:43
  • Nice. By the way, I forgot to remove the `preg_match_all()` from the code above. I just did it, sorry. – filipecsweb May 25 '19 at 19:48
-1

Your going to kick yourself.

$string = 'This is a message with multiple links: http://google.com http://twitter.com http://google.com/qwerty http://facebook.com http://google.com/ytrewq';

preg_match_all('/(^|\s)((http(s)?\:\/\/)?[\w-]+(\.[\w-]+)+[^\s]*[^.,\s])/u', $string, $url);

$links = $url[2];

foreach($links as $link) {
    $string = str_replace($link, '<a href="'.$link.'">'.$link.'</a>', $string);
}

echo $string;

you were overwriting your $final_string instead of replacing $string.