Intereting Posts
PHP MySQL SQL-парсер (INSERT и UPDATE) Спецификация на странице PHP, созданной WordPress Как использовать журналы apache для проверки полной загрузки файлов регулярное выражение в php: взять кратчайшее соответствие Как создать отношения следопытов, используя Полиморфные отношения Многие-Многие с Laravel? Проблема с моей реализацией шаблона Post / Redirect / Get Laravel – Кэширование Красноречивого с частыми обновлениями Как интегрировать array_column () и array_filter () – блокировать динамическое создание таблицы sql-результатов Не удалось открыть поток на file_put_contents в PHP на CentOS 7 Каков самый простой способ добавления сервлетов Java на WAMP-настроенную машину? Как открыть различную информацию для каждого созданного мною полигона? Google maps api v3 Как необязательно добавить запятую и пробел в группу захвата? Общаться с кассовым ящиком с веб-сайта Изменение размера анимированного GIF-файла без уничтожения анимации Маршрутизация для дерева категорий

Как найти все идентификаторы видео YouTube в строке с помощью регулярного выражения?

У меня есть текстовое поле, где пользователи могут писать что угодно.

Например:

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
  • iframe: http://www.youtube.com/embed/NLqAF9hrVbY
  • iframe (безопасный): https://www.youtube.com/embed/NLqAF9hrVbY
  • объект param: http://www.youtube.com/v/NLqAF9hrVbY?fs=1&hl=en_US
  • объект embed: 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
  • ytscreeningroom: http://www.youtube.com/ytscreeningroom?v=NRHVzbJVx8I
  • any / thing / go !: 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
  • nocookie домен: 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>'); } 

Заметки:

  • Часть VIDEO_ID URL-адреса фиксируется в одной и только группе захвата: $1 .
  • Если вы знаете, что ваш текст не содержит предварительно связанных URL-адресов, вы можете безопасно удалить отрицательное утверждение lookahead, которое проверяет это условие (утверждение, начинающееся с комментария: «URL-адрес подтверждения не предварительно связан». ) Это будет скорость несколько повторное выражение.
  • Строка замены может быть изменена. Приведенный выше просто создает ссылку на общий URL-адрес "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: Несколько модификаций:

  • Добавлена ​​версия Javascript: linkifyYouTubeURLs() .
  • Предыдущая версия имела факультативную схему (HTTP-протокол) и, таким образом, соответствовала бы недопустимым URL-адресам. Необходима часть схемы.
  • В предыдущей версии использовался символ привязки символа \b вокруг VIDEO_ID. Однако это не будет работать, если VIDEO_ID начнется или закончится с тире. Исправлено так, что оно обрабатывает это условие.
  • Изменено выражение VIDEO_ID, так что оно должно быть ровно 11 символов.
  • В предыдущей версии не удалось исключить предварительно связанные URL, если у них была строка запроса, следующая за VIDEO_ID. Улучшено утверждение отрицательного прогноза, чтобы исправить это.
  • Добавлено + и % к строке запроса соответствия символов.
  • Изменен разделитель регулярных выражений PHP от: % до 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; } 
  1. Найдите регулярное выражение, которое будет извлекать все ссылки из текста. Google поможет вам там.
  2. Соедините все ссылки и вызовите getHostInfo () для каждого

Хотя ответ от 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:

http://jsfiddle.net/DJSwc/5/

Пытаться

 [^\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)