1

sorry I don't get it. I want to convert a Linktext by using preg_replace with this options:

  1. Text to HTML (incl. Link)
  2. Trim the text until domain (no https:// or http:// or www.)
  3. Shorten a long URL (e.g. to 20 signs)

So, this text:

https://stackoverflow.com/questions/ask

should be converted to this output:

<a HREF="https://stackoverflow.com/questions/ask">stackoverflow.com/quest...</a>

For the question No.1 I have this solution:

$linktext = preg_replace("/([\w]+\:\/\/[\w-?&;#~=\.\/\@]+[\w\/])/", "<a href=\"$1\">$1</a>", $linktext);

...but than it's impossible to change this variable to question 2 and 3.

Any ideas how to fix this to have ONE replace-operation (with arrays or something)?

Sebastian
  • 625
  • 9
  • 22
  • 2
    How about you use `parse_url` instead of regex. http://php.net/manual/en/function.parse-url.php – bassxzero Oct 09 '17 at 18:02
  • 2
    Maybe this thread would be useful, https://stackoverflow.com/questions/46491514/linkify-urls-with-php-trim-outputted-urls-length/ (Also note the comments for `www`) – chris85 Oct 09 '17 at 18:17

4 Answers4

1

I think you're going to fail to find one regex to solve that. However, you could use regular PHP, and that's what I'm going to do in my answer.

$linktext    = 'https://stackoverflow.com/questions/ask';
$linktrimmed = str_replace(['https://', 'http://', 'www.'], '', $linktext); // Remove `https://`, `http://` or `www.`
$linktrimmed = ((strlen($linktrimmed) > 20) ? substr($linktrimmed, 0, 20) . '...' : $linktrimmed); // Shorten to 20 characters and add ellipsis (if neccessary). From https://stackoverflow.com/a/11434149/3088508
$linktext    = "<a href=\"$linktext\">$linktrimmed</a>";
echo $linktext;

This returns:

<a href="https://stackoverflow.com/questions/ask">stackoverflow.com/qu...</a>

eval.in demo

Basically all it does is:

  1. str_replace https://, http:// or www. with an empty string ''
  2. If the url is longer than 20 chars, then substr it and add an ellipsis ... (Borrowed code from this SO post)
  3. Stuff into a html <a> tag.
Ethan
  • 4,295
  • 4
  • 25
  • 44
1

1st, create the below function:

function string_begins_with($string, $search) {
    return (strncmp($string, $search, strlen($search)) == 0) ;
}

Then use this function as follows:

$linktext = "https://www.stackoverflow.com/questions/ask" ;
$trimmedText = $linktext ;

if (string_begins_with($trimmedText, "https://")) { //Removes https://
    $trimmedText = substr($trimmedText, 8) ;
}
if (string_begins_with($trimmedText, "http://")) { //Removes http://
    $trimmedText = substr($trimmedText, 7) ;
}
if (string_begins_with($trimmedText, "www.")) { //Removes www.
    $trimmedText = substr($trimmedText, 4) ;
}
if (strlen($trimmedText) > 20) { //Trim the text to 20 characters
    $trimmedText = substr($trimmedText, 0, 20) . "..." ;
}

echo "<a href='$linktext'>$trimmedText</a>" ;
Mario Rawady
  • 871
  • 7
  • 17
1

Use parse_url

(As @bassxzero suggested) in comments

This drastically simplifies extracting the hostname and path, requiring only a single substr operation to finish meeting your requirements.

function getShortUrl($url) {
    $cleanedUrl = parse_url($url, PHP_URL_HOST) . parse_url($url, PHP_URL_PATH);
    $shortUrl = substr($cleanedUrl, 0, 20);

    if ($shortUrl !== $cleanedUrl) {
        // it's been truncated, add ellipsis
        $shortUrl .= "...";
    }

    return $shortUrl;
}

$linktext = 'https://example.com/test?abc=123';

echo "<a href='$linktext'>". getShortUrl($linktext) ."</a>";
Tony Chiboucas
  • 5,505
  • 1
  • 29
  • 37
  • 1
    @Sebastian, Note: it should be fairly simple to check the performance difference between a solution like this one, and a full regex solution (as you requested). I suspect you'll find this one to be faster. – Tony Chiboucas Oct 09 '17 at 18:33
1

You need preg_replace_callback() together with parse_url(). Basically, find the match, then parse the url, get rid of the scheme, remove www. (I assume you need to keep the subdomain if it's not www), and subtract the remaining characters if there is more than 20 (and add the periods):

<?php
$url = "this is the link: https://stackoverflow.com/questions/ask";    
$linktext = preg_replace_callback("/([\w]+\:\/\/[\w-?&;#~=\.\/\@]+[\w\/])/", function ($m) {
    $url = $m[0];
    $parts = parse_url($url);
    $parts["host"] = str_replace("www.", "", $parts["host"]);
    array_shift($parts); // remove the scheme
    $shortURL = implode("", $parts);
    $shortenedURL = substr($shortURL, 0, 20);
    if (strlen($shortURL) > 20) $shortenedURL .= "...";
    return "<a href=\"".$url."\">".$shortenedURL."</a>";
    var_dump($parts);
}, $url);
echo $linktext;

Demo

ishegg
  • 9,685
  • 3
  • 16
  • 31