Come faccio a trovare tutti gli ID video di YouTube in una stringa utilizzando un'espressione regolare?


91

Ho un campo di testo in cui gli utenti possono scrivere qualsiasi cosa.

Per esempio:

Lorem Ipsum è semplicemente un testo fittizio. http://www.youtube.com/watch?v=DUQi_R4SgWo dell'industria della stampa e della composizione. Lorem Ipsum è stato il testo fittizio standard del settore sin dal 1500, quando una stampante sconosciuta prese una cambusa di caratteri e la mescolò per creare un libro esemplare. È sopravvissuto non solo a cinque secoli, ma anche al passaggio alla composizione elettronica, rimanendo sostanzialmente invariato. http://www.youtube.com/watch?v=A_6gNZCkajU&feature=relmfu È stato reso popolare negli anni '60 con il rilascio di fogli Letraset contenenti passaggi di Lorem Ipsum, e più recentemente con software di desktop publishing come Aldus PageMaker, comprese le versioni di Lorem Ipsum.

Ora vorrei analizzarlo e trovare tutti gli URL dei video di YouTube e i loro ID.

Qualche idea su come funziona?


Risposte:


289

L'URL di un video di YouTube può essere rilevato in una varietà di formati:

  • ultimo breve formato: http://youtu.be/NLqAF9hrVbY
  • iframe: http://www.youtube.com/embed/NLqAF9hrVbY
  • iframe (sicuro): https://www.youtube.com/embed/NLqAF9hrVbY
  • parametro oggetto: http://www.youtube.com/v/NLqAF9hrVbY?fs=1&hl=en_US
  • oggetto incorporato: http://www.youtube.com/v/NLqAF9hrVbY?fs=1&hl=en_US
  • orologio: http://www.youtube.com/watch?v=NLqAF9hrVbY
  • utenti: http://www.youtube.com/user/Scobleizer#p/u/1/1p3vcRhsYGo
  • ytscreeningroom: http://www.youtube.com/ytscreeningroom?v=NRHVzbJVx8I
  • qualsiasi / cosa / va !: http://www.youtube.com/sandalsResorts#p/c/54B8C800269D7C1B/2/PPS-8DMrAn4
  • any / subdomain / too: http://gdata.youtube.com/feeds/api/videos/NLqAF9hrVbY
  • più parametri: http://www.youtube.com/watch?v=spDj54kf-vY&feature=g-vrec
  • la query può contenere un punto: http://www.youtube.com/watch?v=spDj54kf-vY&feature=youtu.be
  • dominio nocookie: http://www.youtube-nocookie.com

Ecco una funzione PHP con un'espressione regolare commentata che corrisponde a ciascuno di questi moduli URL e li converte in collegamenti (se non sono già collegamenti):

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

Ed ecco una versione JavaScript con la stessa identica regex (con commenti rimossi):

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

Appunti:

  • La porzione VIDEO_ID dell'URL viene catturato nel gruppo unico bloccaggio: $1.
  • Se sai che il tuo testo non contiene URL precollegati, puoi rimuovere in sicurezza l'asserzione lookahead negativa che verifica questa condizione (l'asserzione che inizia con il commento: "L'URL dell'affermazione non è pre-collegato" ) . un po 'la regex.
  • La stringa di sostituzione può essere modificata per adattarla. L'unica condizione precedente crea semplicemente un link al generico "http://www.youtube.com/watch?v=VIDEO_ID"URL stile e imposta il testo del link a: "YouTube link: VIDEO_ID".

Modifica 2011-07-05: aggiunto -trattino alla classe di caratteri ID

Modifica 2011-07-17: corretta regex per consumare qualsiasi parte rimanente (ad es. Query ) dell'URL dopo l'ID YouTube. Aggiunto modificatore 'i' ignora maiuscole e minuscole . Funzione rinominata in camelCase. Test di lookahead pre-collegato migliorato.

Modifica 27/07/2011: aggiunti nuovi formati "utente" e "ytscreeningroom" degli URL di YouTube.

Modifica 2011-08-02: semplificato / generalizzato per gestire nuovi URL di YouTube "qualsiasi / cosa / va".

Modifica 2011-08-25: Diverse modifiche:

  • Aggiunta una versione Javascript di: linkifyYouTubeURLs()function.
  • La versione precedente aveva la parte dello schema (protocollo HTTP) opzionale e quindi corrispondeva a URL non validi. Ha reso necessaria la parte dello schema.
  • La versione precedente utilizzava la \bparola ancoraggio di confine attorno a VIDEO_ID. Tuttavia, questo non funzionerà se VIDEO_ID inizia o finisce con un -trattino. Risolto in modo che gestisca questa condizione.
  • Modificata l'espressione VIDEO_ID in modo che debba contenere esattamente 11 caratteri.
  • La versione precedente non era in grado di escludere gli URL pre-collegati se avevano una stringa di query dopo VIDEO_ID. Migliorata l'asserzione di lookahead negativo per risolvere questo problema.
  • Aggiunto +e %alla stringa di query corrispondente alla classe di caratteri.
  • Cambiato versione di PHP espressione regolare delimitatore da: %a: ~.
  • Aggiunta una sezione "Note" con alcune note utili.

Modifica 2011-10-12: la parte host dell'URL di YouTube può ora avere qualsiasi sottodominio (non solo www.).

Modifica 01/05/2012: la sezione dell'URL di consumo può ora consentire l'uso di "-".

Modifica 2013-08-23: aggiunto formato aggiuntivo fornito da @Mei. (La parte della query potrebbe avere un .punto.

Modifica 2013/11/30: Aggiunta formato supplementare fornita da @CRONUS: youtube-nocookie.com.

Modifica 25-01-2016: corretta regex per gestire i casi di errore forniti da CRONUS.


2
Non ho visto una specifica, anche se ne ho cercata una. Ho appena notato il trattino in alcuni link nella natura selvaggia di Internet. Ad esempio: youtube.com/watch?v=CLPk-6_xgiY
cottonBallPaws

1
@littleFluffyKitty: Grazie per l'avviso. Ho aggiornato la risposta per includere il trattino come carattere ID valido.
ridgerunner

1
@ridgerunner: se non sei sicuro di una modifica, puoi eseguire il rollback. Inoltre, come su wikipedia, l'intera storia è conservata con i tuoi crediti. Ho visto che hai davvero coltivato la risposta nel tempo, quindi sarebbe un peccato perderti qui.
hakre

1
Eccone uno che non ha funzionato: youtube.com/watch?v=E1IPnnttL9k&feature=youtu.be
andrebola

1
Funziona alla grande, ma fallisce con questo (nuovo?) Parametro querystring: feature = youtu.be. Cambiare [? = & +% \ W -] * a [? = & +% \ W - \.] * Sulla riga "consuma url rimanente" funziona. Grazie!
Mei Gwilym

10

Ecco un metodo che ho scritto una volta per un progetto che estrae le chiavi video di YouTube e 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. Trova una regex che estrarrà tutti i link da un testo. Google ti aiuterà in questo.
  2. Esegui il ciclo di tutti i collegamenti e chiama getHostInfo () per ciascuno

1
grazie mille! la mod leggera if(strpos($vid_link, 'youtu'))acquisirà l'URL breve youtu.beoltre all'URL comune.
Chamilyan

prego. grazie per l'aggiornamento, ho modificato nella modifica. in una nota a margine, la regex di ridgerunner sembra essere il vero affare e consiglio di usarla per le mie cose semplici. applausi
Christof

esattamente quello che stavo cercando. perfetto amico! +1
blackpla9ue

8

Sebbene la risposta di ridgerunner sia la base per la mia risposta, la sua NON risolve tutti gli URL e non credo che ne sia capace, a causa di più possibili corrispondenze di VIDEO_IDin un URL di YouTube. La mia regex include il suo approccio aggressivo come ultima risorsa, ma prima tenta tutte le corrispondenze comuni, riducendo notevolmente la possibilità di una corrispondenza sbagliata più avanti nell'URL.

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

Gestisce tutti i casi originariamente indicati negli esempi di ridgerunners, più qualsiasi URL che potrebbe avere una sequenza di 11 caratteri più avanti nell'URL. cioè:

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

Ecco un esempio funzionante che testa tutti gli URL di YouTube di esempio:

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


2

Provare

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

Troverai gli ID video nel primo gruppo di acquisizione. Quello che non so è cos'è un ID video valido? Al momento controllo v=e acquisisco tutto -A-Za-z0-9_.

L'ho controllato online qui su Rubular con la tua stringa campione.


2

Uso:

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

Ok, ho creato una funzione tutta mia. Ma credo che sia piuttosto inefficiente. Eventuali miglioramenti sono i benvenuti:

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

Se stai cercando solo link da youtube.com perché vuoi costruire prima un elenco con tutti i link? E penso che non sia necessario usare 3 diverse regex.
stema


1

Il poster originale chiedeva "Vorrei analizzarlo e trovare tutti gli URL dei video di YouTube e i relativi ID". Ho cambiato la risposta più popolare sopra a preg_match e ho restituito l'ID e l'URL del video.

Ottieni l'URL e l'ID di YouTube dal post:

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

0

Trova facilmente un link YouTube da una stringa:

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)

Questo non è solo per YoutTube, ma corrisponderà ad altri URL dal contenuto.
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);

    }

Questo codice in java funziona perfettamente per tutti gli URL di YouTube attualmente.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.