У меня есть текстовое поле, где пользователи могут писать что угодно.
Например:
Lorem Ipsum – просто фиктивный текст. http://www.youtube.com/watch?v=DUQi_R4SgПроизводство печати и верстки. Lorem Ipsum был стандартным фиктивным текстом отрасли с тех пор, как в 1500-х годах, когда неизвестный принтер взял камбуз типа и скремблировал его, чтобы сделать типовую книгу образцов. Он пережил не только пять столетий, но и прыжок в электронный набор, оставаясь практически неизменным. http://www.youtube.com/watch?v=A_6gNZCkajU&feature=relmfu. Он был популяризирован в 1960-х годах с выпуском листов Letraset, содержащих проходы Lorem Ipsum, а в последнее время с программным обеспечением для настольных издательских систем, таких как Aldus PageMaker, включая версии Lorem Ipsum.
Теперь я хотел бы проанализировать его и найти все URL-адреса видео YouTube и их идентификаторы.
Любая идея, как это работает?
URL-адрес видео YouTube можно встретить в различных форматах:
http://youtu.be/NLqAF9hrVbY
http://www.youtube.com/embed/NLqAF9hrVbY
https://www.youtube.com/embed/NLqAF9hrVbY
http://www.youtube.com/v/NLqAF9hrVbY?fs=1&hl=en_US
http://www.youtube.com/v/NLqAF9hrVbY?fs=1&hl=en_US
http://www.youtube.com/watch?v=NLqAF9hrVbY
http://www.youtube.com/user/Scobleizer#p/u/1/1p3vcRhsYGo
http://www.youtube.com/ytscreeningroom?v=NRHVzbJVx8I
http://www.youtube.com/sandalsResorts#p/c/54B8C800269D7C1B/2/PPS-8DMrAn4
http://gdata.youtube.com/feeds/api/videos/NLqAF9hrVbY
http://www.youtube.com/watch?v=spDj54kf-vY&feature=g-vrec
http://www.youtube.com/watch?v=spDj54kf-vY&feature=youtu.be
http://www.youtube-nocookie.com
Вот PHP-функция с запрограммированным регулярным выражением, которая соответствует каждой из этих форм URL-адресов и преобразует их в ссылки (если они уже не являются ссылками):
// Linkify youtube URLs which are not already links. function linkifyYouTubeURLs($text) { $text = preg_replace('~(?#!js YouTubeId Rev:20160125_1800) # Match non-linked youtube URL in the wild. (Rev:20130823) https?:// # Required scheme. Either http or https. (?:[0-9A-Z-]+\.)? # Optional subdomain. (?: # Group host alternatives. youtu\.be/ # Either youtu.be, | youtube # or youtube.com or (?:-nocookie)? # youtube-nocookie.com \.com # followed by \S*? # Allow anything up to VIDEO_ID, [^\w\s-] # but char before ID is non-ID char. ) # End host alternatives. ([\w-]{11}) # $1: VIDEO_ID is exactly 11 chars. (?=[^\w-]|$) # Assert next char is non-ID or EOS. (?! # Assert URL is not pre-linked. [?=&+%\w.-]* # Allow URL (query) remainder. (?: # Group pre-linked alternatives. [\'"][^<>]*> # Either inside a start tag, | </a> # or inside <a> element text contents. ) # End recognized pre-linked alts. ) # End negative lookahead assertion. [?=&+%\w.-]* # Consume any URL (query) remainder. ~ix', '<a href="http://www.youtube.com/watch?v=$1">YouTube link: $1</a>', $text); return $text; }
; // Конец $ YouTubeId.
И вот версия JavaScript с тем же самым регулярным выражением (с удаленными комментариями):
// Linkify youtube URLs which are not already links. function linkifyYouTubeURLs(text) { var re = /https?:\/\/(?:[0-9A-Z-]+\.)?(?:youtu\.be\/|youtube(?:-nocookie)?\.com\S*?[^\w\s-])([\w-]{11})(?=[^\w-]|$)(?![?=&+%\w.-]*(?:['"][^<>]*>|<\/a>))[?=&+%\w.-]*/ig; return text.replace(re, '<a href="http://www.youtube.com/watch?v=$1">YouTube link: $1</a>'); }
Заметки:
$1
. "http://www.youtube.com/watch?v=VIDEO_ID"
и устанавливает текст ссылки: "YouTube link: VIDEO_ID"
. Изменить 2011-07-05: Добавлено -
дефис в класс символов ID
Изменить 2011-07-17: Исправлено регулярное выражение для использования любой оставшейся части (например, запроса ) URL-адреса после идентификатора YouTube. Добавлен модификатор 'i'
ignore-case . Переименована функция camelCase. Улучшенный предварительный тест.
Изменить 2011-07-27: Добавлены новые «пользовательские» и «ytscreeningroom» форматы URL-адресов YouTube.
Редактировать 2011-08-02: Упрощен / обобщен для обработки новых URL-адресов «any / thing / go» YouTube.
Редактировать 2011-08-25: Несколько модификаций:
linkifyYouTubeURLs()
. \b
вокруг VIDEO_ID. Однако это не будет работать, если VIDEO_ID начнется или закончится с тире. Исправлено так, что оно обрабатывает это условие. +
и %
к строке запроса соответствия символов. %
до a: ~
. Редактировать 2011-10-12: хост-часть URL-адреса YouTube может теперь иметь какой-либо субдомен (а не только www.
).
Редактировать 2012-05-01: Раздел URL потребления может теперь разрешать '-'.
Редактировать 2013-08-23: Добавлен дополнительный формат, предоставленный @Mei. (У части запроса может быть точка.
Редактировать 2013-11-30: Добавлен дополнительный формат, предоставленный @CRONUS: youtube-nocookie.com
.
Изменить 2016-01-25: Исправлено регулярное выражение для обработки случая ошибок, предоставляемого CRONUS.
Вот метод, который я когда-то писал для проекта, который извлекает видео-ключи YouTube и Vimeo:
/** * strip important information out of any video link * * @param string link to a video on the hosters page * @return mixed FALSE on failure, array on success */ function getHostInfo ($vid_link) { // YouTube get video id if (strpos($vid_link, 'youtu')) { // Regular links if (preg_match('/(?<=v\=)([\w\d-_]+)/', $vid_link, $matches)) return array('host_name' => 'youtube', 'original_key' => $matches[0]); // Ajax hash tag links else if (preg_match('§([\d\w-_]+)$§i', $vid_link, $matches)) return array('host_name' => 'youtube', 'original_key' => $matches[0]); else return FALSE; } // Vimeo get video id elseif (strpos($vid_link, 'vimeo')) { if (preg_match('§(?<=/)([\d]+)§', $vid_link, $matches)) return array('host_name' => 'vimeo', 'original_key' => $matches[0]); else return FALSE; } else return FALSE; }
Хотя ответ от ridgerunner лежит в основе моего ответа, он НЕ решает для всех URL-адресов, и я не считаю, что он способен на это из-за нескольких возможных совпадений VIDEO_ID
в URL-адресе YouTube. Мое регулярное выражение включает в себя его агрессивный подход в качестве последнего средства, но сначала пытается выполнить все общие соответствия, значительно уменьшая вероятность неправильного совпадения в URL-адресе.
Это регулярное выражение:
/https?:\/\/(?:[0-9A-Z-]+\.)?(?:youtu\.be\/|youtube\.com(?:\/embed\/|\/v\/|\/watch\?v=|\/ytscreeningroom\?v=|\/feeds\/api\/videos\/|\/user\S*[^\w\-\s]|\S*[^\w\-\s]))([\w\-]{11})[?=&+%\w-]*/ig;
Обрабатывает все случаи, на которые ссылаются ссылки в примерах ridgerunners, плюс любой URL-адрес, который может иметь 11-символьную последовательность позже в URL-адресе. то есть:
http://www.youtube.com/watch?v=GUEZCxBcM78&feature=pyv&feature=pyv&ad=10059374899&kw=%2Bwingsuit
Вот рабочий образец, который проверяет все примеры URL-адресов YouTube:
Пытаться
[^\s]*youtube\.com[^\s]*?v=([-\w]+)[^\s]*
Вы найдете идентификаторы видео в первой группе захвата. Что я не знаю, что такое действительный идентификатор видео? На данный момент я проверяю v=
и фиксирую все -A-Za-z0-9_
.
Я проверил его онлайн здесь на rubular с вашей типовой строкой.
Использование:
<?php // The YouTube URL string $youtube_url='http://www.youtube.com/watch?v=8VtUYvwktFQ'; // Use regex to get the video ID $regex='#(?<=v=)[a-zA-Z0-9-]+(?=&)|(?<=[0-9]/)[^&\n]+|(?<=v=)[^&\n]+#'; preg_match($regex, $youtube_url, $id); // Plug that into our HTML ?>
Хорошо, я сделал свою функцию. Но я считаю, что это довольно неэффективно. Любые улучшения приветствуются:
function get_youtube_videos($string) { $ids = array(); // Find all URLs preg_match_all('/(http|https)\:\/\/[a-zA-Z0-9\-\.]+\.[a-zA-Z]{2,3}(\/\S*)?/', $string, $links); foreach ($links[0] as $link) { if (preg_match('~youtube\.com~', $link)) { if (preg_match('/[^=]+=([^?]+)/', $link, $id)) { $ids[] = $id[1]; } } } return $ids; }
Я попробовал простое выражение, чтобы получить только видеоид:
[?&]v=([^&#]*)
Проверьте, что он работает в Интернете здесь, в phpliveregex .
Оригинальный плакат спросил: «Я бы хотел разобрать его и найти все URL-адреса YouTube и их идентификаторы». Я переключил самый популярный ответ выше на preg_match и вернул идентификатор и URL видео.
Получите URL-адрес и идентификатор YouTube из сообщения:
$match[0] = Full URL $match[1] = video ID function get_youtube_id($input) { $input = preg_match('~https?://(?:[0-9A-Z-]+\.)?(?:youtu\.be/|youtube(?:-nocookie)?\.com\S*[^\w\s-])([\w-]{11})(?=[^\w-]|$)(?![?=&+%\w.-]*(?:[\'"][^<>]*>|</a>))[?=&+%\w.-]*~ix', $input, $match); return $match; }
Найти ссылку YouTube легко из строки:
function my_url_search($se_action_data) { $regex = '/https?\:\/\/[^\" ]+/i'; preg_match_all($regex, $se_action_data, $matches); $get_url=array_reverse($matches[0]); return array_unique($get_url); } echo my_url_search($se_action_data)