2012-03-07 9 views
8

Prendiamo questi URL come esempio:modello di RegEx per ottenere l'ID video di YouTube da qualsiasi URL di YouTube

  1. http://www.youtube.com/watch?v=8GqqjVXhfMU&feature=youtube_gdata_player
  2. http://www.youtube.com/watch?v=8GqqjVXhfMU

Questa funzione PHP non otterrà correttamente l'ID in caso 1, ma nel caso 2. Il caso 1 è molto comune, dove QUALSIASI può venire dietro l'ID YouTube.

/** 
* get YouTube video ID from URL 
* 
* @param string $url 
* @return string YouTube video id or FALSE if none found. 
*/ 
function youtube_id_from_url($url) { 
    $pattern = 
     '%^# Match any YouTube URL 
     (?:https?://)? # Optional scheme. Either http or https 
     (?:www\.)?  # Optional www subdomain 
     (?:    # Group host alternatives 
      youtu\.be/ # Either youtu.be, 
     | youtube\.com # or youtube.com 
      (?:   # Group path alternatives 
      /embed/  # Either /embed/ 
      | /v/   # or /v/ 
      | /watch\?v= # or /watch\?v= 
     )    # End path alternatives. 
     )    # End host alternatives. 
     ([\w-]{10,12}) # Allow 10-12 for 11 char YouTube id. 
     $%x' 
     ; 
    $result = preg_match($pattern, $url, $matches); 
    if (false !== $result) { 
     return $matches[1]; 
    } 
    return false; 
} 

Quello che sto pensando è che ci deve essere un modo in cui posso solo cercare il "v =", non importa dove si trova l'URL, e prendere i caratteri dopo. In questo modo, non sarà necessaria alcuna RegEx complessa. È fuori base? Qualche idea per i punti di partenza?

+0

Penso che il problema principale con questo modello sia solo il $ alla fine del modello, che ancorava il modello alla fine della stringa in fase di test. Questo è il motivo per cui il caso 1 non corrisponde, perché non termina con l'ID. – Bendoh

risposta

27
if (preg_match('/youtube\.com\/watch\?v=([^\&\?\/]+)/', $url, $id)) { 
    $values = $id[1]; 
} else if (preg_match('/youtube\.com\/embed\/([^\&\?\/]+)/', $url, $id)) { 
    $values = $id[1]; 
} else if (preg_match('/youtube\.com\/v\/([^\&\?\/]+)/', $url, $id)) { 
    $values = $id[1]; 
} else if (preg_match('/youtu\.be\/([^\&\?\/]+)/', $url, $id)) { 
    $values = $id[1]; 
} 
else if (preg_match('/youtube\.com\/verify_age\?next_url=\/watch%3Fv%3D([^\&\?\/]+)/', $url, $id)) { 
    $values = $id[1]; 
} else { 
// not an youtube video 
} 

Questo è quello che uso per estrarre l'id da un URL di YouTube. Penso che funzioni in tutti i casi.

Nota che alla fine i valori $ = id del video

+1

Questo è molto più generale e cattura la varietà di moduli URL che otterrai da/su YouTube. +1 – Bendoh

+0

@Bendoh perché questo è più generale della risposta selezionata con 'parse_str' - che sembra che catturi perfettamente ogni variabile nell'URL? – Shackrock

+1

La risposta selezionata non acquisisce gli URL del modulo/v/ o incorpora/, solo il modulo che contiene "v" come parametro di query. Inoltre non presta attenzione al nome host del collegamento: estrarrà il valore di "v" da qualsiasi URL con un parametro "v" nella stringa di query. Ad esempio, http://www.youtube.com/v/ihCbVT637aM non verrà analizzato correttamente. – Bendoh

2

Si potrebbe utilizzare parse_url e parse_str:

$query_string = parse_url($url, PHP_URL_QUERY); 
parse_str($query_string); 
echo $v; 
0

Un altro modo facile sta usando parse_str():

<?php 
    $url = 'http://www.youtube.com/watch?v=8GqqjVXhfMU&feature=youtube_gdata_player'; 
    parse_str($url, $yt); 

    // The associative array $yt now contains all of the key-value pairs from the querystring (along with the base 'watch' URL, but doesn't seem you need that) 
    echo $yt['v']; // echos '8GqqjVXhfMU'; 
?> 
+0

Sembra che manchi per primo parse_url, come indicato da altre risposte. Con parse_url funziona. FYI – Shackrock

+0

[ORIG: Non è necessario parse_url. Si potrebbe sostenere che è più pulito, ma - almeno in PHP 5.3.6 - l'URL che precede i parametri di querystring è semplicemente una chiave nell'array.] - EDIT: Ah dannazione, funziona quando c'è un solo parametro QS, ma il la funzione deve essere divisa in &. parse_url sarebbe il modo più corretto. – Morgon

9

Invece di regex. Vi consiglio hightly parse_url() e parse_str():

$url = "http://www.youtube.com/watch?v=8GqqjVXhfMU&feature=youtube_gdata_player"; 
parse_str(parse_url($url, PHP_URL_QUERY), $vars); 
echo $vars['v'];  

Fatto

+0

Perfetto. Grazie. – Shackrock

+2

Questo non funziona con https://www.youtube.com/v/qfx6yf8pux4 –

0

Il parse_url suggerimenti sono buone. Se si vuole veramente una regex è possibile utilizzare questo:

/(?<=v=)[^&]+/` 
0

ho usato i seguenti modelli a causa di YouTube ha un dominio youtube-nocookie.com troppo:

'@youtube(?:-nocookie)?\.com/watch[#\?].*?v=([^"\& ]+)@i', 
'@youtube(?:-nocookie)?\.com/embed/([^"\&\? ]+)@i', 
'@youtube(?:-nocookie)?\.com/v/([^"\&\? ]+)@i', 
'@youtube(?:-nocookie)?\.com/\?v=([^"\& ]+)@i', 
'@youtu\.be/([^"\&\? ]+)@i', 
'@gdata\.youtube\.com/feeds/api/videos/([^"\&\? ]+)@i', 

Nel tuo caso sarebbe unico mezzo per estendere le espressioni esistenti con un optional (-nocookie) per il regolare YouTube.com URL in questo modo:

if (preg_match('/youtube(?:-nocookie)\.com\/watch\?v=([^\&\?\/]+)/', $url, $id)) { 

Se si cambia espressione proposto di non contiene il $ finale, dovrebbe funzionare come previsto. Ho aggiunto anche il -nocookie.

/** 
* get YouTube video ID from URL 
* 
* @param string $url 
* @return string YouTube video id or FALSE if none found. 
*/ 
function youtube_id_from_url($url) { 
    $pattern = 
     '%^# Match any YouTube URL 
     (?:https?://)? # Optional scheme. Either http or https 
     (?:www\.)?  # Optional www subdomain 
     (?:    # Group host alternatives 
      youtu\.be/ # Either youtu.be, 
     |youtube(?:-nocookie)?\.com # or youtube.com and youtube-nocookie 
      (?:   # Group path alternatives 
      /embed/  # Either /embed/ 
      | /v/   # or /v/ 
      | /watch\?v= # or /watch\?v= 
     )    # End path alternatives. 
     )    # End host alternatives. 
     ([\w-]{10,12}) # Allow 10-12 for 11 char YouTube id. 
     %x' 
     ; 
    $result = preg_match($pattern, $url, $matches); 
    if (false !== $result) { 
     return $matches[1]; 
    } 
    return false; 
} 
0

soluzione per ogni link di Youtube:

http://youtube.com/v/dQw4w9WgXcQ 
http://youtube.com/watch?v=dQw4w9WgXcQ 
http://www.youtube.com/watch?feature=player&v=dQw4w9WgXcQ&var2=bla 
http://youtu.be/dQw4w9WgXcQ 

==

https://stackoverflow.com/a/20614061/2165415

0

Ecco una soluzione

/** 
* credits goes to: http://stackoverflow.com/questions/11438544/php-regex-for-youtube-video-id 
* update: mobile link detection 
*/ 
public function parseYouTubeUrl($url) 
{ 
    $pattern = '#^(?:https?://)?(?:www\.)?(?:m\.)?(?:youtu\.be/|youtube\.com(?:/embed/|/v/|/watch\?v=|/watch\?.+&v=))([\w-]{11})(?:.+)?$#x'; 
    preg_match($pattern, $url, $matches); 
    return (isset($matches[1])) ? $matches[1] : false; 
} 

Si può trattare con i collegamenti di telefonia mobile anche.

-1

Ecco la mia funzione per il recupero di ID Youtube!

function getYouTubeId($url) { 
    if (!(strpos($url, 'v=') !== false)) return false; 
    $parse = explode('v=', $url); 
    $code = $parse[1]; 
    if (strlen($code) < 11) return false; 
    $code = substr($code, 0, 11); 
    return $code; 
}