Comment trouver tous les identifiants vidéo YouTube dans une chaîne à l'aide d'une expression régulière?

91

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'industrie de l'impression et de la composition. Lorem Ipsum est le texte factice standard de l'industrie depuis les années 1500, quand un imprimeur inconnu a pris une galère de caractères et l'a brouillée pour en faire un livre de spécimens. Il a survécu non seulement cinq siècles, mais aussi le saut dans la composition électronique, demeurant essentiellement inchangé. http://www.youtube.com/watch?v=A_6gNZCkajU&feature=relmfu Il a été popularisé dans les années 1960 avec la sortie de feuilles Letraset contenant des passages du Lorem Ipsum, et plus récemment avec un logiciel de publication assistée par ordinateur comme Aldus PageMaker comprenant des versions de Lorem Ipsum.

Maintenant, je voudrais l'analyser et trouver toutes les URL de vidéo YouTube et leurs identifiants.

Une idée de comment cela fonctionne?

n00b
la source

Réponses:

289

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

  • dernier format court: http://youtu.be/NLqAF9hrVbY
  • iframe: http://www.youtube.com/embed/NLqAF9hrVbY
  • iframe (sécurisé): https://www.youtube.com/embed/NLqAF9hrVbY
  • paramètre d'objet: http://www.youtube.com/v/NLqAF9hrVbY?fs=1&hl=en_US
  • incorporer l'objet: 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
  • tout va!: http://www.youtube.com/sandalsResorts#p/c/54B8C800269D7C1B/2/PPS-8DMrAn4
  • tout / 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 une expression régulière commentée qui correspond à chacune de ces formes d'URL et les convertit en liens (si ce 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;
}

; // Fin de $ YouTubeId.

Et voici une version JavaScript avec exactement le même regex (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 de recherche négative qui teste cette condition (L'assertion commençant par le commentaire: "Assert URL is not pre-linked." ) Cela accélérera un peu le regex.
  • La chaîne de remplacement peut être modifiée en conséquence. Celui fourni ci - dessus crée simplement un lien vers l'générique "http://www.youtube.com/watch?v=VIDEO_ID"URL de style et définit le texte de lien vers: "YouTube link: VIDEO_ID".

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

Edit 2011-07-17: Correction de l'expression régulière pour consommer toute partie restante (par exemple, requête ) de l'URL suivant l'ID YouTube. Ajout du modificateur Ignorer la 'i' casse . Fonction renommée camelCase. Test d'anticipation pré-lié amélioré.

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

Edit 02/08/2011: simplifié / généralisé pour gérer les nouvelles URL YouTube "tout / chose / va".

Edit 2011-08-25: Plusieurs modifications:

  • Ajout d'une version Javascript de: linkifyYouTubeURLs()function.
  • La version précédente avait la partie schéma (protocole HTTP) facultative et correspondrait donc aux URL invalides. Fait la partie du régime requise.
  • La version précédente utilisait l' \bancre de limite de mot autour du VIDEO_ID. Cependant, cela ne fonctionnera pas si le VIDEO_ID commence ou se termine par un -tiret. Corrigé pour qu'il gère cette condition.
  • L'expression VIDEO_ID a été modifiée pour qu'elle contienne exactement 11 caractères.
  • La version précédente n'a pas réussi à exclure les URL pré-liées si elles avaient une chaîne de requête après VIDEO_ID. Amélioration de l'assertion d'anticipation négative pour résoudre ce problème.
  • Ajouté +et %à la chaîne de requête correspondant à la classe de caractères.
  • Changement version PHP delimiter regex de: %à: ~.
  • Ajout d'une section «Notes» avec quelques notes pratiques.

Edit 2011-10-12: la partie hôte d'URL YouTube peut désormais avoir n'importe quel sous-domaine (pas seulement www.).

Edit 2012-05-01: La section URL de consommation peut désormais autoriser «-».

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

Modifier 30/11/2013: Ajout Format supplémentaire fourni par @CRONUS: youtube-nocookie.com.

Edit 2016-01-25: Correction de l'expression régulière pour gérer les cas d'erreur fournis par CRONUS.

ridgerunner
la source
2
Je n'ai pas vu de spécification, bien que j'en ai recherché une. Je viens de remarquer le tiret dans certains liens dans la nature sauvage d'Internet. Par exemple: youtube.com/watch?v=CLPk-6_xgiY
cottonBallPaws
1
@littleFluffyKitty: Merci pour la mise en garde. Avoir mis à jour la réponse pour inclure le trait d'union comme caractère d'identification valide.
ridgerunner
1
@ridgerunner: Si vous n'êtes pas sûr d'une modification, vous pouvez revenir en arrière. De plus, comme sur wikipedia, toute l'histoire est conservée avec vos crédits. Je vous ai vu vraiment jardiner la réponse au fil du temps, donc ce serait dommage de vous perdre ici.
hakre
1
En voici un qui n'a pas fonctionné: youtube.com/watch?v=E1IPnnttL9k&feature=youtu.be
andrebola
1
Cela fonctionne très bien, mais échoue avec ce (nouveau?) Paramètre de chaîne de requête: feature = youtu.be. Changer [? = & +% \ W -] * en [? = & +% \ W - \.] * Sur votre ligne "consommer l'url restante" fait l'affaire. Merci!
Mei Gwilym
10

Voici une méthode que j'ai écrite une fois pour un projet qui extrait les 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 chacun
Christof
la source
1
grand merci! un léger mod if(strpos($vid_link, 'youtu'))capturera l'url courte youtu.been plus des URL communes.
Chamilyan
vous êtes les bienvenus. merci pour la mise à jour, j'ai édité dans le changement. Par ailleurs, l'expression régulière de ridgerunner semble être la vraie affaire et je recommande de l'utiliser sur mon truc simple. cheers
Christof
exactement ce que je cherchais. place sur mec! +1
blackpla9ue
8

Bien que la réponse de ridgerunner soit la base de ma réponse, elle ne résout PAS toutes les URL et je ne pense pas qu'elle en soit capable, en raison de plusieurs correspondances possibles VIDEO_IDdans une URL YouTube. Mon regex inclut son approche agressive en dernier recours, mais tente d'abord toutes les correspondances courantes, réduisant considérablement la possibilité d'une mauvaise correspondance plus tard dans l'URL.

Cette expression régulière:

/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, ainsi que toute URL qui pourrait avoir 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/

Ezwrighter
la source
2

Essayer

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

Vous trouverez les ID vidéo dans le premier groupe de capture. Ce que je ne sais pas, c'est ce qu'est un ID vidéo valide? Pour le 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.

stema
la source
2

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

D'accord, j'ai fait ma propre fonction. Mais je pense que c'est assez 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;
}
n00b
la source
Si vous recherchez uniquement des liens provenant de youtube.com, pourquoi voulez-vous d'abord créer une liste avec tous les liens? Et je pense que ce n'est pas nécessaire d'utiliser 3 regex différentes.
stema
1

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

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

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

BL Praveen
la source
1

L'affiche originale demandait "Je voudrais 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 preg_match et renvoyé l'identifiant et l'URL de la vidéo.

Obtenez l'URL et l'identifiant YouTube de la publication:

$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;
}
Lee Woodman
la source
0

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)
Mukesh Kumar Bijarniya
la source
Ce n'est pas seulement pour YoutTube, cela correspondra à d'autres URL du contenu.
Rahil Wazir
0
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 parfaitement pour toutes les URL YouTube actuellement.

Sravya Singh
la source