Jak znaleźć wszystkie identyfikatory wideo YouTube w ciągu znaków za pomocą wyrażenia regularnego?

91

Mam pole tekstowe, w którym użytkownicy mogą napisać wszystko.

Na przykład:

Lorem Ipsum to po prostu fikcyjny tekst. http://www.youtube.com/watch?v=DUQi_R4SgWo branży poligraficznej i składu. Lorem Ipsum jest standardowym tekstem zastępczym w branży od XVI wieku, kiedy nieznana drukarka wzięła galerię czcionek i zaszyfrowała ją, aby stworzyć książkę z wzorami. Przetrwał nie tylko pięć wieków, ale także skok do elektronicznego składu, pozostając zasadniczo niezmieniony. http://www.youtube.com/watch?v=A_6gNZCkajU&feature=relmfu Został spopularyzowany w latach sześćdziesiątych XX wieku wraz z wydaniem arkuszy Letraset zawierających fragmenty Lorem Ipsum, a ostatnio z oprogramowaniem do publikowania na komputerze, takim jak Aldus PageMaker, w tym wersje Lorem Ipsum.

Teraz chciałbym go przeanalizować i znaleźć wszystkie adresy URL filmów w YouTube i ich identyfikatory.

Masz jakiś pomysł, jak to działa?

n00b
źródło

Odpowiedzi:

289

Adres URL filmu w serwisie YouTube można napotkać w różnych formatach:

  • najnowszy krótki format: http://youtu.be/NLqAF9hrVbY
  • iframe: http://www.youtube.com/embed/NLqAF9hrVbY
  • iframe (bezpieczne): https://www.youtube.com/embed/NLqAF9hrVbY
  • parametr obiektu: http://www.youtube.com/v/NLqAF9hrVbY?fs=1&hl=en_US
  • osadzenie obiektu: http://www.youtube.com/v/NLqAF9hrVbY?fs=1&hl=en_US
  • zegarek: http://www.youtube.com/watch?v=NLqAF9hrVbY
  • użytkownicy: http://www.youtube.com/user/Scobleizer#p/u/1/1p3vcRhsYGo
  • ytscreeningroom: http://www.youtube.com/ytscreeningroom?v=NRHVzbJVx8I
  • wszystko idzie!: http://www.youtube.com/sandalsResorts#p/c/54B8C800269D7C1B/2/PPS-8DMrAn4
  • dowolna / subdomena / też: http://gdata.youtube.com/feeds/api/videos/NLqAF9hrVbY
  • więcej parametrów: http://www.youtube.com/watch?v=spDj54kf-vY&feature=g-vrec
  • zapytanie może mieć kropkę: http://www.youtube.com/watch?v=spDj54kf-vY&feature=youtu.be
  • domena nocookie: http://www.youtube-nocookie.com

Oto funkcja PHP z skomentowanym wyrażeniem regularnym, która pasuje do każdego z tych formularzy URL i konwertuje je na linki (jeśli nie są już linkami):

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

; // End $ YouTubeId.

A oto wersja JavaScript z dokładnie tym samym wyrażeniem regularnym (z usuniętymi komentarzami):

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

Uwagi:

  • Część VIDEO_ID adresu URL jest ujęte w grupie jedyny przechwytywania: $1.
  • Jeśli wiesz, że Twój tekst nie zawiera żadnych wstępnie połączonych adresów URL, możesz bezpiecznie usunąć negatywne twierdzenie wyprzedzające, które sprawdza ten warunek (stwierdzenie rozpoczynające się od komentarza: „Adres URL potwierdzenia nie jest wstępnie powiązany” ). To przyspieszy nieco podnieść wyrażenie regularne.
  • Łańcuch zamiany można zmodyfikować w celu dopasowania. Ten, pod warunkiem powyżej po prostu tworzy link do rodzajowego "http://www.youtube.com/watch?v=VIDEO_ID"stylu URL i ustawia tekst link do: "YouTube link: VIDEO_ID".

Edycja 2011-07-05: Dodano -łącznik do klasy znaków ID

Edycja 2011-07-17: Naprawiono wyrażenie regularne, które wykorzystywało pozostałą część (np. Zapytanie ) adresu URL po identyfikatorze YouTube. Dodano modyfikator 'i' ignorowania wielkości liter . Zmieniono nazwę funkcji na camelCase. Ulepszony wstępnie połączony test wyprzedzenia.

Edycja 2011-07-27: Dodano nowe formaty „user” i „ytscreeningroom” do adresów URL YouTube.

Edycja 02.08.2011: Uproszczona / uogólniona obsługa nowych adresów URL „cokolwiek / coś / idzie” w YouTube.

Edycja 25.08.2011: Kilka modyfikacji:

  • Dodano wersję JavaScript linkifyYouTubeURLs()funkcji:.
  • Poprzednia wersja miała opcjonalną część schematu (protokołu HTTP) i dlatego pasowała do nieprawidłowych adresów URL. Wymagana część schematu.
  • Poprzednia wersja używała \bzakotwiczenia granicy słowa wokół VIDEO_ID. Jednak to nie zadziała, jeśli VIDEO_ID zaczyna się lub kończy -myślnikiem. Naprawiono tak, że obsługuje ten stan.
  • Zmieniono wyrażenie VIDEO_ID tak, aby miało dokładnie 11 znaków.
  • W poprzedniej wersji nie udało się wykluczyć wstępnie połączonych adresów URL, jeśli po VIDEO_ID występował ciąg zapytania. Poprawiono negatywną asercję wyprzedzającą, aby to naprawić.
  • Dodano +i %do ciągu zapytania pasującego do klasy znaków.
  • Zmieniona wersja PHP regex ogranicznika od: %do a: ~.
  • Dodano sekcję „Notatki” z kilkoma przydatnymi notatkami.

Edytuj 2011-10-12: Część hosta adresu URL YouTube może teraz mieć dowolną subdomenę (nie tylko www.).

Edycja 2012-05-01: Sekcja adresu URL konsumpcji może teraz zezwalać na „-”.

Edycja 23.08.2013: Dodano dodatkowy format dostarczony przez @Mei. (Część zapytania może mieć .kropkę.

Edycja 30.11.2013: Dodano Format dodatkowe świadczone przez @CRONUS: youtube-nocookie.com.

Edycja 2016-01-25: Naprawiono wyrażenie regularne obsługujące przypadki błędów dostarczane przez CRONUS.

Ridgerunner
źródło
2
Nie widziałem specyfikacji, chociaż szukałem jednej. Właśnie zauważyłem myślnik w niektórych linkach w dziczy internetu. Na przykład: youtube.com/watch?v=CLPk-6_xgiY
cottonBallPaws
1
@littleFluffyKitty: Dzięki za ostrzeżenie. Zaktualizowałem odpowiedź, dodając łącznik jako prawidłowy znak identyfikacyjny.
ridgerunner
1
@ridgerunner: Jeśli nie masz pewności co do zmiany, możesz ją cofnąć. Dodatkowo, podobnie jak na Wikipedii, cała historia jest przechowywana z twoimi napisami. Widziałem, jak z biegiem czasu naprawdę opracowywałeś odpowiedź, więc szkoda byłoby cię tutaj stracić.
hakre
1
Oto jeden, który nie zadziałał: youtube.com/watch?v=E1IPnnttL9k&feature=youtu.be
andrebola
1
Działa to świetnie, ale zawodzi z tym (nowym?) Parametrem zapytania: feature = youtu.be. Zmiana [? = & +% \ W -] * na [? = & +% \ W - \.] * W wierszu „zużyj pozostały adres URL” załatwia sprawę. Dzięki!
Mei Gwilym
10

Oto metoda, którą kiedyś napisałem dla projektu, który wyodrębnia klucze wideo YouTube i 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. Znajdź wyrażenie regularne, które wyodrębni wszystkie linki z tekstu. Google Ci w tym pomoże.
  2. Zapętl wszystkie linki i dla każdego z nich wywołaj metodę getHostInfo ()
Christof
źródło
1
wielkie dzięki! niewielki mod if(strpos($vid_link, 'youtu'))przechwyci krótki adres URL youtu.beoprócz zwykłego adresu URL.
Chamilyan
nie ma za co. dzięki za aktualizację, edytowałem w zmianie. na marginesie, wyrażenie regularne ridgerunnera wydaje się być prawdziwą okazją i polecam używanie go zamiast mojej prostej rzeczy. okrzyki
Christof
dokładnie to, czego szukałem. spot on mate! +1
blackpla9ue
8

Chociaż odpowiedź ridgerunnera jest podstawą mojej odpowiedzi, jego NIE rozwiązuje problemu dla wszystkich adresów URL i nie wierzę, że jest w stanie to zrobić, ze względu na wiele możliwych dopasowań VIDEO_IDw adresie URL YouTube. Mój regex zawiera jego agresywne podejście jako ostatnią deskę ratunku, ale najpierw próbuje wszystkich typowych dopasowań, znacznie zmniejszając możliwość błędnego dopasowania w dalszej części adresu URL.

To wyrażenie regularne:

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

Obsługuje wszystkie przypadki pierwotnie przywoływane w przykładach Ridgerunners, a także każdy adres URL, który może mieć sekwencję 11 znaków w dalszej części adresu URL. to znaczy:

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

Oto działający przykład, który testuje wszystkie przykładowe adresy URL YouTube:

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

ezwrighter
źródło
2

Próbować

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

W pierwszej grupie przechwytywania znajdziesz identyfikatory wideo. Nie wiem, co to jest prawidłowy identyfikator wideo? W tej chwili sprawdzam v=i wychwytuję wszystko -A-Za-z0-9_.

Sprawdziłem to online tutaj na rubular z twoim próbnym ciągiem.

stema
źródło
2

Posługiwać się:

<?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
źródło
2

Okej, stworzyłem własną funkcję. Ale uważam, że jest to dość nieefektywne. Wszelkie ulepszenia są mile widziane:

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
źródło
Jeśli szukasz tylko linków z youtube.com, dlaczego chcesz najpierw utworzyć listę ze wszystkimi linkami? Myślę, że użycie 3 różnych wyrażeń regularnych nie jest konieczne.
stema
1

Spróbowałem prostego wyrażenia, aby uzyskać tylko identyfikator wideo:

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

Sprawdź, czy działa online tutaj na phpliveregex .

BL Praveen
źródło
1

Oryginalny plakat pytał: „Chciałbym go przeanalizować i znaleźć wszystkie adresy URL filmów YouTube i ich identyfikatory”. Zmieniłem najpopularniejszą odpowiedź powyżej na preg_match i zwróciłem identyfikator wideo i adres URL.

Uzyskaj adres URL i identyfikator YouTube z posta:

$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
źródło
0

Znajdź łatwo link do YouTube z ciągu:

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
źródło
To nie jest tylko dla YoutTube, będzie pasować do innych adresów URL z treści.
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);

    }

Ten kod w Javie działa obecnie całkowicie dobrze dla wszystkich adresów URL YouTube.

Sravya Singh
źródło