正規表現を使用して文字列内のすべてのYouTubeビデオIDを見つけるにはどうすればよいですか?


91

ユーザーが何でも書けるテキストフィールドがあります。

例えば:

Lorem Ipsumは単なるダミーテキストです。 印刷および組版業界のhttp://www.youtube.com/watch?v=DUQi_R4SgWo。Lorem Ipsumは、1500年代から未知のプリンターがタイプのギャレーを取り、それをスクランブルしてタイプ見本帳を作成して以来、業界標準のダミーテキストでした。それは5世紀も生き残っただけでなく、電子植字への飛躍もあり、本質的に変更されていません。 http://www.youtube.com/watch?v=A_6gNZCkajU&feature=relmfu 1960年代に、Lorem Ipsumのパッセージを含むLetrasetシートがリリースされ、最近ではAldus PageMakerなどのバージョンのLorem Ipsumを含むデスクトップパブリッシングソフトウェアが普及しました。

それを解析して、すべてのYouTubeビデオのURLとそのIDを見つけたいと思います。

それがどのように機能するか考えていますか?


回答:


289

YouTube動画のURLは、さまざまな形式で発生する可能性があります。

  • 最新の短い形式: http://youtu.be/NLqAF9hrVbY
  • iframe: http://www.youtube.com/embed/NLqAF9hrVbY
  • iframe(セキュア): https://www.youtube.com/embed/NLqAF9hrVbY
  • オブジェクトパラメータ: http://www.youtube.com/v/NLqAF9hrVbY?fs=1&hl=en_US
  • オブジェクトの埋め込み: http://www.youtube.com/v/NLqAF9hrVbY?fs=1&hl=en_US
  • 見る: http://www.youtube.com/watch?v=NLqAF9hrVbY
  • ユーザー: http://www.youtube.com/user/Scobleizer#p/u/1/1p3vcRhsYGo
  • ytscreeningroom: http://www.youtube.com/ytscreeningroom?v=NRHVzbJVx8I
  • 何でもあり!: http://www.youtube.com/sandalsResorts#p/c/54B8C800269D7C1B/2/PPS-8DMrAn4
  • 任意/サブドメイン/あまりにも: http://gdata.youtube.com/feeds/api/videos/NLqAF9hrVbY
  • その他のパラメータ: http://www.youtube.com/watch?v=spDj54kf-vY&feature=g-vrec
  • クエリにはドットを含めることができます: http://www.youtube.com/watch?v=spDj54kf-vY&feature=youtu.be
  • nocookieドメイン: http://www.youtube-nocookie.com

以下は、これらの各URLフォームに一致し、リンクに変換するコメント付きの正規表現を持つPHP関数です(まだリンクでない場合)。

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

; // $ YouTubeIdを終了します。

そして、これはまったく同じ正規表現を持つJavaScriptバージョンです(コメントが削除されています)。

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

ノート:

  • URLのVIDEO_ID部分は、唯一のキャプチャグループでキャプチャされます$1
  • テキストに事前にリンクされたURLが含まれていないことがわかっている場合は、この条件をテストする否定先読みアサーション(コメントで始まるアサーション:「URLが事前にリンクされていない」)を安全に削除できます。正規表現を少し上げます。
  • 置換文字列は、必要に応じて変更できます。上記のコードは、一般的な"http://www.youtube.com/watch?v=VIDEO_ID"スタイルのURL へのリンクを作成し、リンクテキストを次のように設定するだけです"YouTube link: VIDEO_ID"

2011-07-05を編集:- ID文字クラスにハイフンを追加

編集2011-07-17: YouTube IDに続くURLの残りの部分(クエリなど)を消費するように正規表現を修正しました。'i' ignore-case修飾子を追加しました。関数の名前をcamelCaseに変更しました。事前リンク先読みテストの改善。

2011-07-27を編集: YouTube URLの新しい「ユーザー」および「ytscreeningroom」形式を追加しました。

2011-08-02を編集:新しい「any / thing / goes」YouTube URLを処理するために簡略化/一般化。

2011-08-25を編集:いくつかの変更:

  • Javascriptバージョンの追加:linkifyYouTubeURLs()関数。
  • 以前のバージョンでは、スキーム(HTTPプロトコル)の部分はオプションだったため、無効なURLに一致していました。スキーム部分を必須にしました。
  • 以前のバージョンで\bは、VIDEO_IDの周囲に単語境界アンカーが使用されていました。ただし、VIDEO_IDが-ダッシュで始まっているか、ダッシュで終わっている場合、これは機能しません。この状態を処理するように修正されました。
  • 正確に11文字になるようにVIDEO_ID式を変更しました。
  • 以前のバージョンでは、VIDEO_IDの後にクエリ文字列が含まれている場合、事前にリンクされたURLを除外できませんでした。これを修正するために否定先読みアサーションを改善しました。
  • +%文字クラスマッチングクエリ文字列に追加されました。
  • PHPバージョンの正規表現区切り文字を:%からa:に変更しました~
  • いくつかの便利なメモを含む「メモ」セクションを追加しました。

2011-10-12を編集: YouTube URLホストパーツにサブドメイン(だけではなくwww.)が含まれるようになりました。

編集2012-05-01: URLの消費セクションで「-」を使用できるようになりました。

2013-08-23を編集: @Meiが提供する追加のフォーマットを追加しました。(クエリ部分に.ドットが含まれる場合があります。

2013-11-30を編集: @CRONUSによって提供される追加のフォーマットを追加:youtube-nocookie.com

2016-01-25を編集: CRONUSが提供するエラーケースを処理するように正規表現を修正しました。


2
スペックを調べたのですが、スペックを見たことがありません。インターネットの荒野でいくつかのリンクのダッシュに気づきました。例:youtube.com/watch
v

1
@littleFluffyKitty:頭を上げてくれてありがとう。有効なID文字としてハイフンを含めるように回答を更新しました。
ridgerunner

1
@ridgerunner:編集に自信がない場合は、ロールバックできます。さらに、ウィキペディアのように、履歴全体がクレジットで保持されます。私はあなたが時間の経過とともに本当に答えを園芸的にしたのを見たので、ここであなたを失うのは苦労でしょう
ハクレ

1
うまくいかないものは次のとおりです: youtube.com/watch
v

1
これはうまく機能しますが、この(新しい?)クエリ文字列パラメーターで失敗します:feature = youtu.be 「残りのURLを消費」の行で[?=&+%\ w-] *を[?=&+%\ w-\。] *に変更すると、うまくいきます。ありがとう!
Mei Gwilym

10

YouTubeと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. テキストからすべてのリンクを抽出する正規表現を見つけます。Googleがお手伝いします。
  2. すべてのリンクをループし、それぞれに対してgetHostInfo()を呼び出します

1
まことにありがとうございます!わずかなmod if(strpos($vid_link, 'youtu'))youtu.be、一般的なURLに加えて短いURLをキャプチャします。
Chamilyan、2011年

どういたしまして。更新してくれてありがとう、私は変更を編集しました。余談ですが、ridgerunnerの正規表現は本当のことのようです。私は単純なものよりも使用することをお勧めします。歓声
クリストフ

まさに私が探していたもの。メイトにスポット!+1
blackpla9ue 2012

8

ridgerunnerの回答は私の回答の基礎ですVIDEO_IDが、YouTubeのURLでの複数の一致の可能性があるため、彼の回答はすべてのURLで解決されるわけではなく、それが可能であるとは思いません。私の正規表現は、最後の手段として彼の積極的なアプローチを含みますが、最初にすべての一般的な一致を試み、URLの後半で誤った一致の可能性を大幅に減らします。

この正規表現:

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

ridgerunnersの例で最初に参照されたすべてのケースに加えて、URLの後ろに11文字のシーケンスが含まれる可能性のあるURLを処理します。つまり:

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

以下は、サンプルのすべてのYouTube URLをテストする実用的なサンプルです。

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


2

試す

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

最初のキャプチャグループにビデオIDがあります。有効なビデオIDとは何ですか。現時点では、v=すべてを確認してキャプチャします-A-Za-z0-9_

私はあなたのサンプル文字列を使ってルーブルでオンラインチェックしまし


2

使用する:

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

さて、私は自分の機能を作りました。しかし、それはかなり非効率的だと思います。どんな改善も歓迎です:

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

youtube.comからのリンクのみを探している場合、最初にすべてのリンクを含むリストを作成するのはなぜですか。また、3つの異なる正規表現を使用する必要はないと思います。
Stea


1

元の投稿者は、「解析して、すべてのYouTubeビデオのURLとそのIDを見つけたい」と尋ねました。上記の最も一般的な回答をpreg_matchに切り替え、動画のIDとURLを返しました。

投稿からYouTubeのURLとIDを取得します。

$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

文字列からYouTubeリンクを簡単に見つける:

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)

これはYoutTubeだけのものではなく、コンテンツの他のURLと一致します。
Rahil Wazir 2014

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

    }

Javaのこのコードは、現時点ですべてのYouTubeのURLに対してまったく問題なく機能します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.