¿Cómo encuentro todos los ID de video de YouTube en una cadena usando una expresión regular?

91

Tengo un campo de texto donde los usuarios pueden escribir cualquier cosa.

Por ejemplo:

Lorem Ipsum es simplemente texto ficticio. http://www.youtube.com/watch?v=DUQi_R4SgWo de la industria de la impresión y la composición tipográfica. Lorem Ipsum ha sido el texto de relleno estándar de la industria desde la década de 1500, cuando un impresor desconocido tomó una galera de tipos y la mezcló para hacer un libro de muestras tipo. Ha sobrevivido no solo a cinco siglos, sino también al salto a la composición tipográfica electrónica, permaneciendo esencialmente sin cambios. http://www.youtube.com/watch?v=A_6gNZCkajU&feature=relmfu Se popularizó en la década de 1960 con el lanzamiento de hojas de Letraset que contenían pasajes de Lorem Ipsum y, más recientemente, con software de autoedición como Aldus PageMaker que incluía versiones de Lorem Ipsum.

Ahora me gustaría analizarlo y encontrar todas las URL de los videos de YouTube y sus identificadores.

¿Alguna idea de cómo funciona?

n00b
fuente

Respuestas:

289

La URL de un video de YouTube se puede encontrar en una variedad de formatos:

  • último formato corto: http://youtu.be/NLqAF9hrVbY
  • iframe: http://www.youtube.com/embed/NLqAF9hrVbY
  • iframe (seguro): https://www.youtube.com/embed/NLqAF9hrVbY
  • parámetro de objeto: http://www.youtube.com/v/NLqAF9hrVbY?fs=1&hl=en_US
  • objeto incrustado: http://www.youtube.com/v/NLqAF9hrVbY?fs=1&hl=en_US
  • reloj: http://www.youtube.com/watch?v=NLqAF9hrVbY
  • usuarios: http://www.youtube.com/user/Scobleizer#p/u/1/1p3vcRhsYGo
  • ytscreeningroom: http://www.youtube.com/ytscreeningroom?v=NRHVzbJVx8I
  • ¡todo vale!: http://www.youtube.com/sandalsResorts#p/c/54B8C800269D7C1B/2/PPS-8DMrAn4
  • cualquier / subdominio / también: http://gdata.youtube.com/feeds/api/videos/NLqAF9hrVbY
  • más parámetros: http://www.youtube.com/watch?v=spDj54kf-vY&feature=g-vrec
  • la consulta puede tener un punto: http://www.youtube.com/watch?v=spDj54kf-vY&feature=youtu.be
  • dominio nocookie: http://www.youtube-nocookie.com

Aquí hay una función PHP con una expresión regular comentada que coincide con cada uno de estos formularios de URL y los convierte en enlaces (si aún no son enlaces):

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

; // Fin de $ YouTubeId.

Y aquí hay una versión de JavaScript con la misma expresión regular (sin comentarios):

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

Notas:

  • La parte ID_DE_VÍDEO de la URL es capturado en el grupo único de captura: $1.
  • Si sabe que su texto no contiene ninguna URL enlazada previamente, puede eliminar de forma segura la aserción de búsqueda anticipada negativa que prueba esta condición (la afirmación que comienza con el comentario: "La URL de afirmación no está enlazada previamente" ). Esto acelerará sube un poco la expresión regular.
  • La cadena de reemplazo se puede modificar para adaptarla. La proporcionada por encima de simplemente crea un enlace al genérico "http://www.youtube.com/watch?v=VIDEO_ID"URL estilo y establece el texto del enlace a: "YouTube link: VIDEO_ID".

Editar 2011-07-05: Se agregó un -guión a la clase de identificación de caracteres

Editar 2011-07-17: Se corrigió la expresión regular para consumir cualquier parte restante (por ejemplo, consulta ) de la URL después de la ID de YouTube. Se agregó 'i' un modificador de ignorar mayúsculas y minúsculas . Función renombrada a camelCase. Prueba de anticipación predefinida mejorada.

Editar 2011-07-27: Se agregaron nuevos formatos de "usuario" y "ytscreeningroom" de las URL de YouTube.

Editar 2011-08-02: simplificado / generalizado para manejar las nuevas URL de YouTube de "cualquier cosa o cosa".

Editar 2011-08-25: Varias modificaciones:

  • Se agregó una versión de Javascript de: linkifyYouTubeURLs()function.
  • La versión anterior tenía la parte del esquema (protocolo HTTP) opcional y, por lo tanto, coincidiría con las URL no válidas. Hizo el esquema parte requerida.
  • La versión anterior usaba la \bpalabra anclaje de límite alrededor de VIDEO_ID. Sin embargo, esto no funcionará si VIDEO_ID comienza o termina con un -guión. Se corrigió para que maneje esta condición.
  • Se modificó la expresión VIDEO_ID para que tenga exactamente 11 caracteres.
  • La versión anterior no podía excluir las URL vinculadas previamente si tenían una cadena de consulta después de VIDEO_ID. Se mejoró la afirmación de anticipación negativa para solucionar este problema.
  • Se agregó +y %a la cadena de consulta coincidente de clase de carácter.
  • Se cambió la versión PHP de expresiones regulares delimitador de: %a: ~.
  • Se agregó una sección de "Notas" con algunas notas útiles.

Editar 2011-10-12: La parte del host de la URL de YouTube ahora puede tener cualquier subdominio (no solo www.).

Editar 2012-05-01: La sección de URL de consumo ahora puede permitir '-'.

Editar 2013-08-23: formato adicional proporcionado por @Mei. (La parte de la consulta puede tener un .punto.

Editar 11/30/2013: Añadido formato adicional proporcionada por @CRONUS: youtube-nocookie.com.

Editar 2016-01-25: expresión regular fija para manejar el caso de error proporcionado por CRONUS.

ridgerunner
fuente
2
No he visto una especificación, aunque busqué una. Acabo de notar el guión en algunos enlaces en la naturaleza de Internet. Por ejemplo: youtube.com/watch?v=CLPk-6_xgiY
cottonBallPaws
1
@littleFluffyKitty: Gracias por avisar. Se actualizó la respuesta para incluir el guión como un carácter de identificación válido.
ridgerunner
1
@ridgerunner: si no está seguro con una edición, puede retroceder. Además, como en Wikipedia, todo el historial se mantiene con sus créditos. He visto que realmente lograste la respuesta con el tiempo, por lo que sería una pena perderte aquí.
Hakre
1
Aquí hay uno que no funcionó: youtube.com/watch?v=E1IPnnttL9k&feature=youtu.be
andrebola
1
Esto funciona muy bien, pero falla con este (¿nuevo?) Parámetro de cadena de consulta: feature = youtu.be. Cambiar [? = & +% \ W -] * a [? = & +% \ W - \.] * En su línea "consume url restante" funciona. ¡Gracias!
Mei Gwilym
10

Aquí hay un método que escribí una vez para un proyecto que extrae claves de video de YouTube y 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. Busque una expresión regular que extraiga todos los enlaces de un texto. Google te ayudará allí.
  2. Haga un bucle de todos los enlaces y llame a getHostInfo () para cada uno
Christof
fuente
1
¡muchas gracias! leve mod if(strpos($vid_link, 'youtu'))capturará la URL corta youtu.beademás de la URL común.
Chamilyan
De nada. gracias por la actualización, edité el cambio. en una nota al margen, la expresión regular de ridgerunner parece ser el verdadero negocio y recomiendo usarlo en mi cosa simple. saludos
Christof
Exactamente lo que estaba buscando. perfecto mate! +1
blackpla9ue
8

Si bien la respuesta de ridgerunner es la base de mi respuesta, la suya NO resuelve todas las URL y no creo que sea capaz de hacerlo, debido a las múltiples coincidencias posibles VIDEO_IDen una URL de YouTube. Mi expresión regular incluye su enfoque agresivo como último recurso, pero primero intenta todas las coincidencias comunes, lo que reduce enormemente la posibilidad de una coincidencia incorrecta más adelante en la URL.

Esta expresión regular:

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

Maneja todos los casos a los que se hace referencia originalmente en los ejemplos de ridgerunners, además de cualquier URL que pueda tener una secuencia de 11 caracteres más adelante en la URL. es decir:

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

Aquí hay una muestra funcional que prueba todas las URL de muestra de YouTube:

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

ezwrighter
fuente
2

Tratar

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

Encontrará las ID de video en el primer grupo de captura. Lo que no sé es qué es una identificación de video válida. Por el momento, busco v=y capturo todo -A-Za-z0-9_.

Lo verifiqué en línea aquí en rubular con su cadena de muestra.

stema
fuente
2

Utilizar:

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

De acuerdo, hice una función propia. Pero creo que es bastante ineficiente. Cualquier mejora es bienvenida:

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
fuente
Si solo busca enlaces de youtube.com, ¿por qué desea crear al principio una lista con todos los enlaces? Y creo que no es necesario usar 3 expresiones regulares diferentes.
stema
1

Probé una expresión simple para obtener solo el videoid:

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

Compruébelo trabajando en línea aquí en phpliveregex .

BL Praveen
fuente
1

El cartel original preguntaba "Me gustaría analizarlo y encontrar todas las URL de los videos de YouTube y sus identificadores". Cambié la respuesta más popular anterior a preg_match y devolví la identificación del video y la URL.

Obtenga la URL y el ID de YouTube de la publicación:

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

Encuentre un enlace de YouTube fácilmente desde una cadena:

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
fuente
Esto no es solo para YoutTube, coincidirá con otras URL del contenido.
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);

    }

Este código en Java funciona absolutamente bien para todas las URL de YouTube en la actualidad.

Sravya Singh
fuente