2012-11-20 36 views
13

我正在嘗試驗證我的應用程序的YouTube網址。使用Regex驗證YouTube網址

到目前爲止,我有以下幾點:

// Set the youtube URL 
$youtube_url = "www.youtube.com/watch?v=vpfzjcCzdtCk"; 

if (preg_match("/((http\:\/\/){0,}(www\.){0,}(youtube\.com){1} || (youtu\.be){1}(\/watch\?v\=[^\s]){1})/", $youtube_url) == 1) 
{ 
    echo "Valid"; 
else 
{ 
    echo "Invalid"; 
} 

我希望驗證YouTube網址的以下變化:

  • 有和無的http://
  • 帶和不帶WWW。
  • 隨着網址youtube.com和youtu.be
  • 必須有/手錶?ν=
  • 必須具有獨特的視頻線(在上面的 「vpfzjcCzdtCk」 的例子)

然而,我不要以爲我有我的邏輯正確,因爲某種原因,它返回爲:www.youtube.co/watch?v=vpfzjcCzdtCk(請注意,我已經與.co寫它不正確,而不是.com

+0

的可能的複製[正則表達式的Youtube URL(HTTP ://stackoverflow.com/questions/8306963/regular-expression-youtube-url) –

回答

31

有很多冗餘的在你的正則表達式(還有,在leaning toothpick syndrome)。其實,這不過應該產生的結果:

$rx = '~ 
    ^(?:https?://)?       # Optional protocol 
    (?:www[.])?        # Optional sub-domain 
    (?:youtube[.]com/watch[?]v=|youtu[.]be/) # Mandatory domain name (w/ query string in .com) 
    ([^&]{11})        # Video id of 11 characters as capture group 1 
    ~x'; 

$has_match = preg_match($rx, $url, $matches); 

// if matching succeeded, $matches[1] would contain the video ID 

一些注意事項:

  • 使用波浪號字符~作爲分隔符,以避免\.
  • 使用[.]代替LTS以提高可視度,並避免LTS 。 (「特殊」人物 - 如點. - 在字符類沒有影響(方括號內))
  • ,使正則表達式更加「可讀」,你可以使用x修飾符(其中有進一步的影響;見the docs on Pattern modifiers) ,這也允許在正則表達式中的評論
  • 可以使用非捕獲組來抑制捕獲:(?: <pattern>)。這使得表達更有效率。

可選,從(或多或少完整)URL中提取值,你可能想使parse_url()使用:

$url = 'http://youtube.com/watch?v=VIDEOID'; 
$parts = parse_url($url); 
print_r($parts); 

輸出:

Array 
(
    [scheme] => http 
    [host] => youtube.com 
    [path] => /watch 
    [query] => v=VIDEOID 
) 

驗證域名和提取視頻ID留給讀者作爲練習。


我放棄了下面的評論戰;感謝Toni Oriol,正則表達式現在也適用於short(youtu.be)網址。

+0

哇,這是一個驚人的答案。我認爲這需要看一下手冊來解釋我爲什麼工作,但它非常棒!謝謝! – Luke

+0

如何驗證與文本框的YouTube鏈接 - http://stackoverflow.com/questions/28735459/how-to-validate-you-tube-url-in-client-side-in-text-box – Hitesh

+1

不驗證以下URL youtu.be/pmpqdwvzzzm – muaaz

3

請嘗試:

// Set the youtube URL 
$youtube_url = "www.youtube.com/watch?v=vpfzjcCzdtCk"; 

if (preg_match("/^((http\:\/\/){0,}(www\.){0,}(youtube\.com){1}|(youtu\.be){1}(\/watch\?v\=[^\s]){1})$/", $youtube_url) == 1) 
{ 
    echo "Valid"; 
} 
else 
{ 
    echo "Invalid"; 
} 

你有||這在沒有^ $的情況下是可以的。

3

這應做到:

$valid = preg_match("/^(https?\:\/\/)?(www\.)?(youtube\.com|youtu\.be)\/watch\?v\=\w+$/", $youtube_url); 
if ($valid) { 
    echo "Valid"; 
} else { 
    echo "Invalid"; 
} 
+1

這不接受視頻IDS連字符 – aphoe

5

正則表達式另一種方法是parse_url()

$parts = parse_url($url); 
if ($parts['host'] == 'youtube.com' && ...) { 
    // your code 
} 

雖然更多的代碼,它是更可讀的,並且因此更易於維護。

1

我推遲到這個頁面上的其他答案解析URL語法,但對於的YouTube ID值本身,你可以更具體一點,我在下面的答案描述上StackExchange/webapps中

Format for ID of YouTube video - https://webapps.stackexchange.com/a/101153/141734


視頻ID

對於VIDEOID,它是一個8字節(64位)整數。對8字節數據應用Base64編碼需要11個字符。然而,由於每個Base64編碼字符傳送剛好6位,這種分配實際上可以容納多達11 × 6 = 66位 - 超過正是我們需要的有效載荷2位的盈餘。多餘的位被設置爲零,這具有排除某些字符從編碼字符串的最後位置出現的效果。特別地,VIDEOID將始終具有以下之一結束:

{ A, E, I, M, Q, U, Y, c, g, k, o, s, w, 0, 4, 8 } 

因此,對於VIDEOID正則表達式(正則表達式)將如下所示:

[-_A-Za-z0-9]{10}[AEIMQUYcgkosw048] 

頻道或播放列表Id

channelId and playlistId字符串是由Base64編碼的128位(16字節)二進制整數生成的。再次在這裏,每個Base64的計算正確地預測了觀察到的字符串長度22個字符。在這種情況下,輸出能夠編碼22 × 6 = 132比特,剩餘4比特;那些零最終限制了大多數64個字母符號出現在最後位置,並且只有4個符合條件。所有的channelID字符串在下面的一個結尾:

{ A, Q, g, w } 

這爲我們提供了一個的channelID正則表達式:

[-_A-Za-z0-9]{21}[AQgw] 
+0

感謝您添加這個額外的信息格倫!因此,resex的更具體的版本將是https://regex101.com/r/pveXvY/1 – Luke