Varkoume
Varkoume

Reputation: 15

PHP Regular Expression to find the first youtube link

I'm trying to find an expression to keep only the first youtube link I find in $render variable.

$render="some text here https://www.youtube.com/watch?v=fJ9rUzIMcZQ https://www.youtube.com/watch?v=fJ9rUzIMcZQ some text here https://www.youtube.com/watch?v=fJ9rUzIMcZQhttps://www.youtube.com/watch?v=fJ9rUzIMcZQ";

$prefix = "https://www.youtube.com/watch?v=";
$index = strpos($render, $prefix) + strlen($prefix);
$youtube = substr($render, $index);
$youtube = strtok($youtube,' ');
$regex="@(https):\/\/(www\.)?youtube.com/watch\?v=[\w_-].* *@";
preg_match($string, $render, $matches, PREG_OFFSET_CAPTURE);
$render = preg_replace($regex, "", $render);
$render = substr_replace($render, $matches[0][0], $matches[0][1], 0);
echo $render;

What I get

https://www.youtube.com/watch?v=fJ9rUzIMcZQ  ://www.youtube.com/watch?v=fJ9rUzIMcZQ

What I want to get

https://www.youtube.com/watch?v=fJ9rUzIMcZQ

P.S. The last two links are combined

Upvotes: 1

Views: 452

Answers (2)

Gigi
Gigi

Reputation: 157

Using numeric delimiters is not-so-future proof in my opinion, this could work as well:

(https):\/\/(www\.)?youtube.com\/watch\?v=[\w-].*?(?=(\s|\b|https?))

The positive lookahead "(?=(\s|\b|https?))" will match (but not include) a delimiter whitespace or word bound, furthermore it will recognize the beginning of a new URL with http(s) and will not match it, the lazy loading will match less characters up to the end of the link. I also changed the set because "\w" already includes the underscore. If tomorrow YT decides to make URLs that are 24 characters you'll be fine anyways, until the latter part still remains included in the set. This cover all cases of space, newline and even recognize the two URLs that are attached.

Upvotes: 0

Ethan
Ethan

Reputation: 4375

Try limiting how much the regex can match, so it doesn't spill over into the next url:

(?:https:\/\/www\.)?youtube\.com\/watch\?v=[\w_-]{1,11}

regex101 demo

$render = "some text here youtube.com/watch?v=fJ9rUzIMcZQ youtube.com/watch?v=fJ9rUzIMcZQ some text here youtube.com/watch?v=fJ9rUzIMcZQhttps://www.youtube.com/...";
preg_match('/(?:https:\/\/www\.)?youtube\.com\/watch\?v=[\w_-]{1,11}/', $render, $matches);
$render = $matches[0];
echo $render; // => youtube.com/watch?v=fJ9rUzIMcZQ

3v41.org demo

Upvotes: 1

Related Questions