web-dev-qa-db-fra.com

Comment trouver tous les identifiants de vidéos YouTube d'une chaîne en utilisant une expression régulière?

J'ai un champ de texte où les utilisateurs peuvent écrire n'importe quoi.

Par exemple:

Lorem Ipsum est simplement un texte factice . http://www.youtube.com/watch?v=DUQi_R4SgWo de l'impression et de la composition industrie. Lorem Ipsum a été le Texte factice standard de l'industrie jamais depuis les années 1500, quand un inconnu l’imprimeur a pris une cuisine de type et brouillé pour faire un spécimen type livre. Il a survécu non seulement cinq siècles, mais aussi le saut dans composition électronique, restant essentiellement inchangé . http://www.youtube.com/watch?v=A_6gNZCkajU&feature=relmfu Il a été popularisé dans les années 1960 avec la sortie des feuilles de Letraset contenant des passages de Lorem Ipsum, et plus récemment avec la publication assistée par ordinateur des logiciels comme Aldus PageMaker y compris les versions de Lorem Ipsum.

Maintenant, j'aimerais analyser et trouver toutes les URL de vidéos YouTube et leurs identifiants.

Une idée de comment ça marche?

88
n00b

Une URL de vidéo YouTube peut être rencontrée dans différents formats:

  • dernier format court: http://youtu.be/NLqAF9hrVbY
  • iframe: http://www.youtube.com/embed/NLqAF9hrVbY
  • iframe (secure): https://www.youtube.com/embed/NLqAF9hrVbY
  • objet param: http://www.youtube.com/v/NLqAF9hrVbY?fs=1&hl=en_US
  • objet incorporé: http://www.youtube.com/v/NLqAF9hrVbY?fs=1&hl=en_US
  • regarder: http://www.youtube.com/watch?v=NLqAF9hrVbY
  • utilisateurs: http://www.youtube.com/user/Scobleizer#p/u/1/1p3vcRhsYGo
  • ytscreeningroom: http://www.youtube.com/ytscreeningroom?v=NRHVzbJVx8I
  • n'importe quel/chose/va !: http://www.youtube.com/sandalsResorts#p/c/54B8C800269D7C1B/2/PPS-8DMrAn4
  • n'importe quel/sous-domaine/aussi: http://gdata.youtube.com/feeds/api/videos/NLqAF9hrVbY
  • plus de paramètres: http://www.youtube.com/watch?v=spDj54kf-vY&feature=g-vrec
  • la requête peut avoir un point: http://www.youtube.com/watch?v=spDj54kf-vY&feature=youtu.be
  • domaine nocookie: http://www.youtube-nocookie.com

Voici une fonction PHP avec un regex commenté qui correspond à chacun de ces formulaires d'URL et les convertit en liens (s'ils ne sont pas déjà des liens):

// 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;
}

; // Terminez $ YouTubeId.

Et voici une version JavaScript avec exactement la même expression régulière (avec les commentaires supprimés):

// 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>');
}

Remarques:

  • La partie VIDEO_ID de l'URL est capturée dans le groupe de capture unique: $1.
  • Si vous savez que votre texte ne contient aucune URL pré-liée, vous pouvez supprimer en toute sécurité l'assertion lookahead négative qui teste cette condition (l'assertion commençant par le commentaire: "L'URL d'assertion n'est pas pré-liée." ) Cela accélérera quelque peu la regex.
  • La chaîne de remplacement peut être modifiée en conséquence. Celui fourni ci-dessus crée simplement un lien vers l'URL générique de style "http://www.youtube.com/watch?v=VIDEO_ID" et définit le texte du lien sur: "YouTube link: VIDEO_ID".

Edit 2011-07-05: Ajout de - trait d'union à la classe de caractères d'ID

Edit 2011-07-17: Fixe regex pour consommer toute partie restante (par exemple query) de l'URL suivant l'identifiant YouTube. Ajout du modificateur 'i'ignore-case. Fonction renommée en camelCase. Amélioration du test d'anticipation pré-lié.

Edit 2011-07-27: Ajout de nouveaux formats "utilisateur" et "ytscreeningroom" des URL YouTube.

Edit 2011-08-02: Simplifié/généralisé pour gérer les nouvelles URL YouTube "n'importe quel/chose/va".

Edit 2011-08-25: Plusieurs modifications:

  • Ajout d'une version Javascript de la fonction: linkifyYouTubeURLs().
  • La version précédente avait la partie schéma (protocole HTTP) facultative et correspondait donc aux URL non valides. Fait la partie de régime requise.
  • La version précédente utilisait l'ancre de limite \b Word autour de VIDEO_ID. Toutefois, cela ne fonctionnera pas si VIDEO_ID commence ou se termine par un tiret -. Fixé pour qu'il gère cette condition.
  • Changement de l'expression VIDEO_ID afin qu'il doit comporter exactement 11 caractères.
  • La version précédente n'a pas réussi à exclure les URL déjà liées si une chaîne de requête suivait VIDEO_ID. Amélioration de l’affirmation négative de look look pour résoudre ce problème.
  • Ajout de + et % à la chaîne de requête correspondant à la classe de caractères.
  • Le délimiteur de regex version PHP de: % a été remplacé par un: ~.
  • Ajout d'une section "Notes" avec quelques notes utiles.

Edit 2011-10-12: La partie hôte de l'URL YouTube peut désormais contenir n'importe quel sous-domaine (pas uniquement www.).

Edit 2012-05-01: La section d'utilisation de l'URL peut désormais autoriser la présence de '-'.

Edit 2013-08-23: Ajout du format supplémentaire fourni par @Mei. (La partie requête peut avoir un point ..

Edit 2013-11-30: Ajout du format supplémentaire fourni par @CRONUS: youtube-nocookie.com.

Edit 2016-01-25: Correction d'une expression rationnelle pour gérer le cas d'erreur fourni par CRONUS.

283
ridgerunner

Voici une méthode que j'ai écrite pour un projet qui extrait des clés vidéo YouTube et 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. Trouvez une expression régulière qui extraira tous les liens d'un texte. Google vous y aidera.
  2. Bouclez tous les liens et appelez getHostInfo () pour chaque
10
Christof

Bien que la réponse de ridgerunner soit la base de ma réponse, elle ne résout pas pour toutes les URL et je ne pense pas qu'elle en soit capable, en raison des multiples correspondances possibles de VIDEO_ID dans une URL YouTube. Ma regex inclut son approche agressive en dernier recours, mais essaie d’abord toutes les correspondances communes, ce qui réduit considérablement la possibilité d’une mauvaise correspondance plus tard dans l’URL.

Cette regex: 

/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;

Gère tous les cas référencés à l'origine dans les exemples de ridgerunners, plus toute URL pouvant éventuellement contenir une séquence de 11 caractères plus tard dans l'URL. c'est à dire: 

http://www.youtube.com/watch?v=GUEZCxBcM78&feature=pyv&feature=pyv&ad=10059374899&kw=%2Bwingsuit

Voici un exemple de travail qui teste tous les exemples d'URL YouTube:

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

8
ezwrighter

Essayer

[^\s]*youtube\.com[^\s]*?v=([-\w]+)[^\s]*

Vous trouverez les identifiants vidéo dans le premier groupe de capture. Ce que je ne sais pas, c'est ce qu'est un identifiant vidéo valide? En ce moment, je vérifie v= et capture tout -A-Za-z0-9_.

Je l'ai vérifié en ligne ici sur rubular avec votre exemple de chaîne.

2
stema

Utilisation:

<?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
?>
2
Noor Khan

D'accord, j'ai créé ma propre fonction. Mais je crois que c'est plutôt inefficace… .. Toute amélioration est la bienvenue:

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;
}
2
n00b

J'ai essayé une expression simple pour obtenir uniquement le videoid:

[?&]v=([^&#]*)

Vérifiez qu'il fonctionne en ligne ici à phpliveregex .

1
B L Praveen

L’affiche originale demandait: "Je souhaite l’analyser et trouver toutes les URL de vidéos YouTube et leurs identifiants." J'ai remplacé la réponse la plus populaire ci-dessus par un preg_match et renvoyé l'ID et l'URL de la vidéo.

Obtenir l'URL et l'ID YouTube de l'article:

$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;
}
1
Lee Woodman
String urlid="" ;
String  url="http://www.youtube.com/watch?v=0zM4nApSvMg#t=0m10s";
Pattern pattern =Pattern.compile("(?:http|https|)(?::\\/\\/|)(?:www.|)(?:youtu\\.be\\/|youtube\\.com(?:\\/embed\\/|\\/v\\/|\\/watch\\?v=|\\/ytscreeningroom\\?v=|\\/feeds\\/api\\/videos\\/|\\/user\\\\S*[^\\w\\-\\s]|\\S*[^\\w\\-\\s]))([\\w\\-\\_]{11})[a-z0-9;:@#?&%=+\\/\\$_.-]*");
Matcher result = pattern.matcher(url);
    if (result.find())
    {
         urlid=result.group(1);

    }

Ce code en Java fonctionne absolument bien pour toutes les URL youtube actuellement.

0
Sravya Singh

Trouvez facilement un lien YouTube à partir d'une chaîne:

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)
0