2012-03-07 28 views
8

Tomemos estas URL como ejemplo:patrón de expresión para obtener el ID de vídeo de YouTube desde cualquier URL de YouTube

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

Esta función PHP no obtener correctamente el ID de caso 1, pero lo será en el caso 2. El caso 1 es muy común, donde CUALQUIERA puede aparecer detrás de la ID de 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; 
} 

Lo que estoy pensando es que tiene que haber una manera en la que sólo puede buscar la "v =", no importa dónde se encuentra en la URL, y llevar a los personajes después de eso. De esta manera, no se necesitará ningún RegEx complejo. ¿Está fuera de la base? Alguna idea para los puntos de partida?

+0

Creo que el principal problema con este patrón es solo el $ al final del patrón, que ancla el patrón al final de la cadena que se está probando. Esta es la razón por la que el Caso 1 no coincide, porque no termina con la ID. – Bendoh

Respuesta

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 
} 

Esto es lo que yo uso para extraer el identificador de una URL de YouTube. Creo que funciona en todos los casos.

Tenga en cuenta que en los valores finales $ = id del vídeo

+1

Esto es mucho más general y capta la variedad de formularios de URL que obtendrá de/a YouTube. +1 – Bendoh

+0

@Bendoh ¿por qué es esto más general que la respuesta seleccionada con/parse_str' - que parece que capta perfectamente todas las variables en la URL? – Shackrock

+1

La respuesta seleccionada no capturará las URL del formulario/v/ o incrustó/, solo el formulario que contiene 'v' como parámetro de consulta. Tampoco presta atención al nombre de host del enlace; simplemente extraerá el valor de 'v' de cualquier URL con un parámetro 'v' en la cadena de consulta. Por ejemplo, http://www.youtube.com/v/ihCbVT637aM no se analizará correctamente. – Bendoh

2

Se podía utilizar parse_url y parse_str:

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

Otra manera fácil está utilizando 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

Parece que le falta parse_url primero, como otras respuestas indican. Con parse_url funciona. FYI – Shackrock

+0

[ORIG: No hay necesidad de parse_url. Se podría argumentar que es más limpio, pero, al menos en PHP 5.3.6, la URL que precede a los parámetros de la cadena de consulta es simplemente una clave en la matriz.] - EDITAR: Ah, maldita sea, esto funciona cuando solo hay un parámetro QS, pero el la función debe dividirse en &. parse_url sería la forma más correcta. – Morgon

9

En vez de expresiones regulares. Recomiendo encarecidamente parse_url() y 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'];  

Hecho

+0

Perfecto. Gracias. – Shackrock

+2

Esto no funciona con https://www.youtube.com/v/qfx6yf8pux4 –

0

El parse_url sugerencias son buenas. Si realmente quieres una expresión regular puede utilizar esta:

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

He utilizado los siguientes patrones ya que YouTube tiene un dominio youtube-nocookie.com también:

'@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', 

En su caso lo haría Sólo significa extender las expresiones existentes con un accesorio opcional (-nocookie) para la dirección URL habitual YouTube.com así:

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

Si cambia de expresión propuesto no contiene la $ final, debería funcionar como lo pretendía. Añadí la -nocookie también.

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

solución para cualquier enlace de 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

Aquí es una solución

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

Se puede tratar con enlaces móviles también.

-1

¡Aquí está mi función para recuperar la identificación de 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; 
} 
Cuestiones relacionadas