[php] 정규식을 사용하여 문자열에서 모든 YouTube 동영상 ID를 찾으려면 어떻게하나요?

사용자가 무엇이든 쓸 수있는 텍스트 필드가 있습니다.

예를 들면 :

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 시트가 출시되면서 대중화되었으며 최근에는 Lorem Ipsum 버전을 포함한 Aldus PageMaker와 같은 데스크톱 출판 소프트웨어로 대중화되었습니다.

이제 그것을 파싱하고 모든 YouTube 동영상 URL과 ID를 찾고 싶습니다.

어떻게 작동하는지 아십니까?



답변

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이 포함되어 있지 않다는 것을 알고있는 경우이 조건을 테스트하는 부정적 미리보기 어설 션을 안전하게 제거 할 수 있습니다 ( “Assert URL is not pre-linked.” 주석으로 시작하는 어설 션 ). 이렇게하면 속도가 빨라집니다. 정규식을 다소 올리십시오.
  • 교체 문자열은 이에 맞게 수정할 수 있습니다. 위에 제공된 것은 단순히 일반 "http://www.youtube.com/watch?v=VIDEO_ID"스타일 URL에 대한 링크를 만들고 링크 텍스트를 다음으로 설정합니다 "YouTube link: VIDEO_ID".

2011-07-05 편집 :- ID char 클래스에 하이픈 추가

2011-07-17 수정 : YouTube ID 다음에 오는 URL의 나머지 부분 (예 : 쿼리 ) 을 사용하도록 정규식을 수정했습니다 . 'i' 대소 문자 무시 수정자를 추가했습니다 . 함수의 이름이 camelCase로 변경되었습니다. 사전 연결된 미리보기 테스트가 개선되었습니다.

2011-07-27 수정 : YouTube URL의 새로운 ‘사용자’및 ‘ytscreeningroom’형식이 추가되었습니다.

2011-08-02 수정 : 새로운 ‘무엇이든 / 진행’YouTube URL을 처리하도록 단순화 / 일반화되었습니다.

2011-08-25 수정 : 몇 가지 수정 :

  • 자바 스크립트 버전 추가 : linkifyYouTubeURLs()function.
  • 이전 버전에는 스키마 (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에서 제공하는 오류 케이스를 처리하도록 정규식을 수정했습니다.


답변

다음은 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 ()를 호출합니다.


답변

ridgerunner의 대답이 내 대답의 기초이지만 그의 모든 URL을 해결하지는 못하며 VIDEO_IDYouTube 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/


답변

시험

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

첫 번째 캡처 그룹에서 비디오 ID를 찾을 수 있습니다. 내가 모르는 것은 유효한 비디오 ID가 무엇입니까? 현재 나는 v=모든 -A-Za-z0-9_.

나는 당신의 샘플 문자열과 함께 여기 루 블러 로 온라인 에서 그것을 확인했습니다 .


답변

사용하다:

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


답변

좋아, 나는 내 자신의 기능을 만들었다. 그러나 나는 그것이 매우 비효율적이라고 생각합니다. 모든 개선 사항을 환영합니다.

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


답변

videoid 만 얻기 위해 간단한 표현을 시도했습니다.

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

phpliveregex에서 온라인으로 작동하는지 확인하십시오 .