Làm cách nào để tìm tất cả id video YouTube trong một chuỗi bằng regex?


91

Tôi có một trường văn bản nơi người dùng có thể viết bất cứ thứ gì.

Ví dụ:

Lorem Ipsum chỉ đơn giản là văn bản giả. http://www.youtube.com/watch?v=DUQi_R4SgWo của ngành in ấn và sắp chữ. Lorem Ipsum đã trở thành văn bản giả tiêu chuẩn của ngành kể từ những năm 1500, khi một nhà in không xác định lấy một dãy loại và xáo trộn nó để tạo thành một cuốn sách mẫu. Nó đã tồn tại không chỉ năm thế kỷ, mà còn là bước nhảy vọt trong lĩnh vực sắp chữ điện tử, về cơ bản vẫn không thay đổi. http://www.youtube.com/watch?v=A_6gNZCkajU&feature=relmfu Nó được phổ biến vào những năm 1960 với việc phát hành các tờ Letraset chứa các đoạn Lorem Ipsum và gần đây hơn với phần mềm xuất bản trên máy tính để bàn như Aldus PageMaker bao gồm các phiên bản của Lorem Ipsum.

Bây giờ tôi muốn phân tích cú pháp nó và tìm tất cả các URL video YouTube và id của chúng.

Bất kỳ ý tưởng làm thế nào đó hoạt động?


Câu trả lời:


289

URL video YouTube có thể gặp ở nhiều định dạng:

  • định dạng ngắn mới nhất: http://youtu.be/NLqAF9hrVbY
  • iframe: http://www.youtube.com/embed/NLqAF9hrVbY
  • iframe (bảo mật): https://www.youtube.com/embed/NLqAF9hrVbY
  • đối tượng param: http://www.youtube.com/v/NLqAF9hrVbY?fs=1&hl=en_US
  • đối tượng nhúng: http://www.youtube.com/v/NLqAF9hrVbY?fs=1&hl=en_US
  • đồng hồ đeo tay: http://www.youtube.com/watch?v=NLqAF9hrVbY
  • người dùng: http://www.youtube.com/user/Scobleizer#p/u/1/1p3vcRhsYGo
  • ytscreeningroom: http://www.youtube.com/ytscreeningroom?v=NRHVzbJVx8I
  • bất kỳ / điều / đi !: http://www.youtube.com/sandalsResorts#p/c/54B8C800269D7C1B/2/PPS-8DMrAn4
  • bất kỳ / tên miền phụ / quá: http://gdata.youtube.com/feeds/api/videos/NLqAF9hrVbY
  • các thông số khác: http://www.youtube.com/watch?v=spDj54kf-vY&feature=g-vrec
  • truy vấn có thể có dấu chấm: http://www.youtube.com/watch?v=spDj54kf-vY&feature=youtu.be
  • miền nocookie: http://www.youtube-nocookie.com

Đây là một hàm PHP với regex được nhận xét phù hợp với từng dạng URL này và chuyển chúng thành liên kết (nếu chúng chưa phải là liên kết):

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

; // Kết thúc $ YouTubeId.

Và đây là một phiên bản JavaScript với cùng một regex (với các nhận xét đã bị xóa):

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

Ghi chú:

  • Phần VIDEO_ID của URL được chụp ở nhóm một và chỉ chụp: $1.
  • Nếu bạn biết rằng văn bản của mình không chứa bất kỳ URL nào được liên kết trước, bạn có thể xóa một cách an toàn xác nhận phủ định trên trang đầu để kiểm tra điều kiện này (Xác nhận bắt đầu bằng nhận xét: "URL xác nhận không được liên kết trước" ). Điều này sẽ tăng tốc độ lên regex phần nào.
  • Chuỗi thay thế có thể được sửa đổi cho phù hợp. Người cung cấp ở trên chỉ đơn giản là tạo ra một liên kết đến chung "http://www.youtube.com/watch?v=VIDEO_ID"URL phong cách và đặt link text: "YouTube link: VIDEO_ID".

Chỉnh sửa 2011-07-05: Đã thêm -dấu gạch nối vào lớp ký tự ID

Chỉnh sửa 2011/07/17: Đã sửa lỗi regex để sử dụng bất kỳ phần nào còn lại (ví dụ: truy vấn ) của URL sau ID YouTube. Đã thêm 'i' công cụ sửa đổi chữ hoa-thường . Đã đổi tên chức năng thành camelCase. Cải thiện kiểm tra trang đầu được liên kết trước.

Chỉnh sửa 2011/07/27: Đã thêm định dạng "người dùng" và "ytscreeningroom" mới của URL YouTube.

Chỉnh sửa 2011-08-02: Đơn giản hóa / tổng quát hóa để xử lý các URL YouTube "bất kỳ / điều gì / đi" mới.

Chỉnh sửa 2011-08-25: Một số sửa đổi:

  • Đã thêm phiên bản Javascript của: linkifyYouTubeURLs()function.
  • Phiên bản trước có phần lược đồ (giao thức HTTP) tùy chọn và do đó sẽ khớp với các URL không hợp lệ. Thực hiện phần chương trình bắt buộc.
  • Phiên bản trước đã sử dụng ký tự liên kết \branh giới từ xung quanh VIDEO_ID. Tuy nhiên, điều này sẽ không hoạt động nếu VIDEO_ID bắt đầu hoặc kết thúc bằng -dấu gạch ngang. Đã sửa để nó xử lý tình trạng này.
  • Đã thay đổi biểu thức VIDEO_ID để biểu thức phải dài chính xác 11 ký tự.
  • Phiên bản trước không thể loại trừ các URL được liên kết trước nếu chúng có chuỗi truy vấn theo sau VIDEO_ID. Đã cải tiến xác nhận tiêu cực để khắc phục điều này.
  • Đã thêm +%vào chuỗi truy vấn phù hợp với lớp ký tự.
  • Thay đổi phiên bản PHP regex delimiter từ: %đến a: ~.
  • Đã thêm phần "Ghi chú" với một số ghi chú hữu ích.

Chỉnh sửa 2011-10-12: Phần lưu trữ URL của YouTube hiện có thể có bất kỳ tên miền phụ nào (không chỉ www.).

Chỉnh sửa 2012-05-01: Phần URL tiêu thụ bây giờ có thể cho phép '-'.

Chỉnh sửa 2013-08-23: Đã thêm định dạng bổ sung do @Mei cung cấp. (Phần truy vấn có thể có .dấu chấm.

Sửa 2013/11/30: Thêm định dạng thêm được cung cấp bởi @CRONUS: youtube-nocookie.com.

Chỉnh sửa 2016-01-25: Đã sửa lỗi regex để xử lý trường hợp lỗi do CRONUS cung cấp.


2
Tôi đã không thấy một thông số kỹ thuật, mặc dù tôi đã tìm kiếm một trong số đó. Tôi chỉ nhận thấy dấu gạch ngang trong một số liên kết trong mạng internet. Ví dụ: youtube.com/watch?v=CLPk-6_xgiY
cottonBallPaws,

1
@littleFluffyKitty: Cảm ơn bạn đã quan tâm. Đã cập nhật câu trả lời để bao gồm dấu gạch nối làm ký tự ID hợp lệ.
ridgerunner

1
@ridgerunner: Nếu không tự tin với bản chỉnh sửa, bạn có thể quay lại. Ngoài ra, giống như trên wikipedia, toàn bộ lịch sử được lưu giữ với các khoản tín dụng của bạn. Tôi đã thấy bạn thực sự làm vườn câu trả lời theo thời gian, vì vậy sẽ rất khó nếu bạn bỏ qua ở đây.
hakre

1
Dưới đây là một trong những điều đó không làm việc: youtube.com/watch?v=E1IPnnttL9k&feature=youtu.be
andrebola

1
Điều này hoạt động tốt, nhưng không thành công với chuỗi truy vấn (mới?) Này param: feature = youtu.be. Thay đổi [? = & +% \ W -] * thành [? = & +% \ W - \.] * Trên dòng "tiêu thụ url còn lại" của bạn là một mẹo nhỏ. Cảm ơn!
Mei Gwilym

10

Đây là một phương pháp tôi đã từng viết cho một dự án trích xuất các khóa video của YouTube và 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. Tìm một regex sẽ trích xuất tất cả các liên kết từ một văn bản. Google sẽ giúp bạn ở đó.
  2. Vòng tất cả các liên kết và gọi getHostInfo () cho mỗi liên kết

1
cảm ơn rất nhiều! mod nhẹ if(strpos($vid_link, 'youtu'))sẽ nắm bắt url ngắn youtu.bengoài url phổ biến.
Chamilyan

không có gì. cảm ơn cho bản cập nhật, tôi đã chỉnh sửa trong thay đổi. một lưu ý nhỏ, regex của ridgerunner có vẻ là thỏa thuận thực sự và tôi khuyên bạn nên sử dụng nó thay vì điều đơn giản của tôi. chúc mừng
Christof

Chính xác những gì tôi đang tìm kiếm. ngay tại chỗ! +1
blackpla9ue

8

Mặc dù câu trả lời của ridgerunner là cơ sở cho câu trả lời của tôi, nhưng câu trả lời của anh ấy KHÔNG giải quyết được cho tất cả các url và tôi không tin rằng nó có khả năng giải quyết được điều đó, do có thể có nhiều kết quả trùng khớp VIDEO_IDtrong một URL YouTube. Regex của tôi bao gồm cách tiếp cận tích cực của anh ấy như là phương sách cuối cùng, nhưng thử tất cả các kết hợp phổ biến trước, giảm đáng kể khả năng kết hợp sai sau này trong URL.

Regex này:

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

Xử lý tất cả các trường hợp được tham chiếu ban đầu trong các ví dụ về ridgerunners, cộng với bất kỳ url nào có thể có chuỗi 11 ký tự sau này trong url. I E:

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

Đây là một mẫu hoạt động kiểm tra tất cả các url YouTube mẫu:

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


2

Thử

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

Bạn sẽ tìm thấy các ID video 'trong nhóm chụp đầu tiên. Điều tôi không biết là ID video hợp lệ là gì? Tại thời điểm này, tôi kiểm tra v=và chụp tất cả -A-Za-z0-9_.

Tôi đã kiểm tra nó trực tuyến tại đây trên rubular với chuỗi mẫu của bạn.


2

Sử dụng:

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

Được rồi, tôi đã tạo một chức năng của riêng mình. Nhưng tôi tin rằng nó khá kém hiệu quả. Mọi cải tiến đều được hoan nghênh:

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

Nếu bạn chỉ tìm kiếm các liên kết từ youtube.com, tại sao ban đầu bạn lại muốn xây dựng một danh sách với tất cả các liên kết? Và tôi nghĩ rằng không cần thiết phải sử dụng 3 regex khác nhau.
stema


1

Người đăng ban đầu hỏi "Tôi muốn phân tích cú pháp nó và tìm tất cả các URL video YouTube và id của chúng." Tôi đã chuyển câu trả lời phổ biến nhất ở trên thành preg_match và trả lại id và URL của video.

Nhận URL và ID YouTube từ bài đăng:

$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

Dễ dàng tìm thấy liên kết YouTube từ một chuỗi:

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)

Điều này không chỉ dành cho YoutTube, nó sẽ khớp với các url khác từ nội dung.
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);

    }

Mã này trong java hoạt động hoàn toàn tốt cho tất cả các url youtube hiện tại.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.