Wie finde ich alle YouTube-Video-IDs in einer Zeichenfolge mithilfe eines regulären Ausdrucks?

91

Ich habe ein Textfeld, in das Benutzer alles schreiben können.

Beispielsweise:

Lorem Ipsum ist einfach Dummy-Text. http://www.youtube.com/watch?v=DUQi_R4SgWo der Druck- und Satzindustrie. Lorem Ipsum ist seit dem 16. Jahrhundert der Standard-Dummy-Text der Branche, als ein unbekannter Drucker eine Galeere vom Typ nahm und sie zu einem Musterbuch verschlüsselte. Es hat nicht nur fünf Jahrhunderte überlebt, sondern auch den Sprung in den elektronischen Satz, der im Wesentlichen unverändert geblieben ist. http://www.youtube.com/watch?v=A_6gNZCkajU&feature=relmfu Es wurde in den 1960er Jahren mit der Veröffentlichung von Letraset-Blättern mit Lorem Ipsum-Passagen und in jüngerer Zeit mit Desktop-Publishing-Software wie Aldus PageMaker einschließlich Versionen von Lorem Ipsum populär gemacht.

Jetzt möchte ich es analysieren und alle YouTube-Video-URLs und ihre IDs finden.

Irgendeine Idee, wie das funktioniert?

n00b
quelle

Antworten:

289

Eine YouTube-Video-URL kann in verschiedenen Formaten gefunden werden:

  • aktuelles Kurzformat: http://youtu.be/NLqAF9hrVbY
  • iframe: http://www.youtube.com/embed/NLqAF9hrVbY
  • iframe (sicher): https://www.youtube.com/embed/NLqAF9hrVbY
  • Objektparameter: http://www.youtube.com/v/NLqAF9hrVbY?fs=1&hl=en_US
  • Objekteinbettung: http://www.youtube.com/v/NLqAF9hrVbY?fs=1&hl=en_US
  • sehen: http://www.youtube.com/watch?v=NLqAF9hrVbY
  • Benutzer: http://www.youtube.com/user/Scobleizer#p/u/1/1p3vcRhsYGo
  • ytscreeningroom: http://www.youtube.com/ytscreeningroom?v=NRHVzbJVx8I
  • alles geht!: http://www.youtube.com/sandalsResorts#p/c/54B8C800269D7C1B/2/PPS-8DMrAn4
  • jede / Subdomain / auch: http://gdata.youtube.com/feeds/api/videos/NLqAF9hrVbY
  • Weitere Parameter: http://www.youtube.com/watch?v=spDj54kf-vY&feature=g-vrec
  • Abfrage kann Punkt haben: http://www.youtube.com/watch?v=spDj54kf-vY&feature=youtu.be
  • Nocookie-Domain: http://www.youtube-nocookie.com

Hier ist eine PHP-Funktion mit einem kommentierten regulären Ausdruck, der mit jedem dieser URL-Formulare übereinstimmt und sie in Links konvertiert (sofern es sich nicht bereits um Links handelt):

// 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 beenden.

Und hier ist eine JavaScript-Version mit genau demselben regulären Ausdruck (mit entfernten Kommentaren):

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

Anmerkungen:

  • Der VIDEO_ID-Teil der URL wird in der einzigen Erfassungsgruppe erfasst : $1.
  • Wenn Sie wissen, dass Ihr Text keine vorverknüpften URLs enthält, können Sie die negative Lookahead-Behauptung, die diese Bedingung testet, sicher entfernen. (Die Behauptung beginnt mit dem Kommentar: "URL bestätigen ist nicht vorverknüpft." ) Dies beschleunigt sich den regulären Ausdruck etwas erhöhen.
  • Die Ersetzungszeichenfolge kann entsprechend geändert werden. Die oben angegebene erstellt einfach einen Link zur "http://www.youtube.com/watch?v=VIDEO_ID"URL im generischen Stil und setzt den Linktext auf : "YouTube link: VIDEO_ID".

Edit 2011-07-05:- Bindestrich zur ID- Zeichenklasse hinzugefügt

Edit 2011-07-17: Regex behoben , um alle verbleibenden Teile (z. B. Abfragen ) der URL nach der YouTube-ID zu verbrauchen . Modifikator für 'i' Groß- und Kleinschreibung hinzugefügt . Funktion in camelCase umbenannt. Verbesserter vorverknüpfter Lookahead-Test.

Bearbeiten 2011-07-27: Neue Formate "Benutzer" und "ytscreeningroom" von YouTube-URLs hinzugefügt.

Edit 2011-08-02: Vereinfacht / verallgemeinert, um neue YouTube-URLs "any / thing / goes" zu verarbeiten.

Edit 2011-08-25: Mehrere Änderungen:

  • Eine Javascript-Version von: linkifyYouTubeURLs()function wurde hinzugefügt .
  • In früheren Versionen war der Teil des Schemas (HTTP-Protokoll) optional und stimmte daher mit ungültigen URLs überein. Das Schema Teil erforderlich gemacht.
  • In der vorherigen Version wurde \bder Wortbegrenzungsanker um die VIDEO_ID verwendet. Dies funktioniert jedoch nicht, wenn die VIDEO_ID mit einem -Bindestrich beginnt oder endet . Behoben, dass es diese Bedingung behandelt.
  • Der Ausdruck VIDEO_ID wurde so geändert, dass er genau 11 Zeichen lang sein muss.
  • In der vorherigen Version konnten vorverknüpfte URLs nicht ausgeschlossen werden, wenn nach der VIDEO_ID eine Abfragezeichenfolge vorhanden war. Die negative Lookahead-Behauptung wurde verbessert, um dies zu beheben.
  • Hinzugefügt +und %zu Zeichenklasse passenden Query - String.
  • Der Regex-Begrenzer für die PHP-Version wurde von: %in: geändert ~.
  • Es wurde ein Abschnitt "Notizen" mit einigen praktischen Notizen hinzugefügt.

Bearbeiten 2011-10-12: Der YouTube-URL-Host-Teil kann jetzt eine beliebige Subdomain haben (nicht nur www.).

Edit 2012-05-01: Der Abschnitt zum Konsumieren von URLs kann jetzt '-' zulassen.

Bearbeiten 23.08.2013: Zusätzliches Format von @Mei hinzugefügt. (Der Abfrageteil kann einen .Punkt haben.

Bearbeiten 30.11.2013: Zusätzliches Format von @CRONUS hinzugefügt : youtube-nocookie.com.

Edit 2016-01-25: Regex behoben , um den von CRONUS bereitgestellten Fehlerfall zu behandeln.

Ridgerunner
quelle
2
Ich habe keine Spezifikation gesehen, obwohl ich eine gesucht habe. Ich habe gerade den Strich in einigen Links in der Wildnis des Internets bemerkt. Zum Beispiel: youtube.com/watch?v=CLPk-6_xgiY
CottonBallPaws
1
@littleFluffyKitty: Danke für das Heads Up. Die Antwort wurde aktualisiert und enthält nun den Bindestrich als gültiges ID-Zeichen.
Ridgerunner
1
@ridgerunner: Wenn Sie mit einer Bearbeitung nicht sicher sind, können Sie ein Rollback durchführen. Zusätzlich wird wie bei Wikipedia die gesamte Geschichte mit Ihren Credits geführt. Ich habe gesehen, dass Sie die Antwort im Laufe der Zeit wirklich im Garten gehalten haben, also wäre es schade, Sie hier zu verlieren.
hakre
1
Hier ist eine, die nicht funktioniert hat: youtube.com/watch?v=E1IPnnttL9k&feature=youtu.be
andrebola
1
Dies funktioniert hervorragend, schlägt jedoch mit diesem (neuen?) Querystring-Parameter fehl: feature = youtu.be. Das Ändern von [? = & +% \ W -] * in [? = & +% \ W - \.] * In Ihrer Zeile "Verbleibende URL verbrauchen" reicht aus. Vielen Dank!
Mei Gwilym
10

Hier ist eine Methode, die ich einmal für ein Projekt geschrieben habe, das YouTube- und Vimeo-Videotasten extrahiert:

/**
 *  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. Suchen Sie einen regulären Ausdruck, der alle Links aus einem Text extrahiert. Google wird Ihnen dort helfen.
  2. Schleife alle Links und rufe für jeden getHostInfo () auf
Christof
quelle
1
vielen Dank! Ein leichter Mod if(strpos($vid_link, 'youtu'))erfasst die kurze URL youtu.bezusätzlich zu den allgemeinen URLs.
Chamilyan
Bitte. danke für das update, das ich in der änderung bearbeitet habe. Nebenbei bemerkt, Ridgerunners Regex scheint das echte Geschäft zu sein, und ich empfehle, ihn über meine einfache Sache zu verwenden. Prost
Christof
genau das, wonach ich gesucht habe. genau richtig Kumpel! +1
blackpla9ue
8

Während die Antwort von ridgerunner die Grundlage für meine Antwort ist, löst sich seine NICHT für alle URLs und ich glaube nicht, dass sie dazu in der Lage ist, da mehrere Übereinstimmungen VIDEO_IDin einer YouTube-URL möglich sind. Mein regulärer Ausdruck beinhaltet seinen aggressiven Ansatz als letzten Ausweg, versucht jedoch zuerst alle gängigen Übereinstimmungen, wodurch die Möglichkeit einer falschen Übereinstimmung später in der URL erheblich verringert wird.

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

Behandelt alle Fälle, auf die ursprünglich in Ridgerunners-Beispielen verwiesen wurde, sowie alle URLs, die möglicherweise später in der URL eine 11-stellige Sequenz haben. dh:

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

Hier ist ein Arbeitsbeispiel, das alle YouTube-Beispiel-URLs testet:

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

ezwrighter
quelle
2

Versuchen

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

Sie finden die Video-IDs in der ersten Erfassungsgruppe. Was ich nicht weiß ist, was eine gültige Video-ID ist? Im Moment überprüfe ich v=alles und fange es ein -A-Za-z0-9_.

Ich habe es hier online auf Rubular mit Ihrer Beispielzeichenfolge überprüft .

Stema
quelle
2

Verwenden:

<?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
quelle
2

Okay, ich habe eine eigene Funktion gemacht. Aber ich glaube, es ist ziemlich ineffizient. Verbesserungen sind willkommen:

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
quelle
Wenn du nur nach Links von youtube.com suchst, warum möchtest du zuerst eine Liste mit allen Links erstellen? Und ich denke, es ist nicht notwendig, 3 verschiedene Regexe zu verwenden.
Stema
1

Ich habe einen einfachen Ausdruck versucht, um nur die Video-ID zu erhalten:

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

Überprüfen Sie es online bei phpliveregex .

BL Praveen
quelle
1

Auf dem Originalposter wurde gefragt: "Ich möchte es analysieren und alle YouTube-Video-URLs und ihre IDs finden." Ich habe die oben genannte beliebteste Antwort auf preg_match umgestellt und die Video-ID und die URL zurückgegeben.

Holen Sie sich die YouTube-URL und -ID aus dem Beitrag:

$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
quelle
0

Finden Sie einfach einen YouTube-Link aus einer Zeichenfolge:

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
quelle
Dies gilt nicht nur für YoutTube, sondern auch für andere URLs aus Inhalten.
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);

    }

Dieser Code in Java funktioniert derzeit für alle YouTube-URLs einwandfrei.

Sravya Singh
quelle