18

アプリケーションのYouTubeURLを検証しようとしています。

これまでのところ、私は次のものを持っています:

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

YoutubeURLの次のバリエーションを検証したいと思います。

  • http://の有無にかかわらず
  • wwwの有無にかかわらず。
  • URLyoutube.comとyoutu.beを使用
  • / watch?v=が必要です
  • 一意のビデオ文字列が必要です(上記の例では「vpfzjcCzdtCk」)

ただし、論理が正しいとは思いません。何らかの理由で、次の場合にtrueが返されるためです。www.youtube.co/watch?v=vpfzjcCzdtCk.co.com

4

5 に答える 5

38

この正規表現には多くの冗長性があります(また、傾いた楊症候群)。ただし、これにより結果が得られるはずです。

$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修飾子を使用できます(これにはさらに影響があります。パターン修飾子に関するドキュメントを参照してください)。これにより、正規表現でのコメントも可能になります。
  • 非キャプチャグループを使用すると、キャプチャを抑制できます(?: <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のおかげで、正規表現は短い(youtu.be)URLでも機能するようになりました。

于 2012-11-20T15:13:43.930 に答える
5

正規表現の代わりになりますparse_url()

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

それはより多くのコードですが、より読みやすく、したがってより保守しやすくなっています。

于 2012-11-20T15:15:20.790 に答える
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";
}

あなたが持っていた|| いずれにせよ、^$がなくても大丈夫です。

于 2012-11-20T15:09:25.180 に答える
3

これはそれを行う必要があります:

$valid = preg_match("/^(https?\:\/\/)?(www\.)?(youtube\.com|youtu\.be)\/watch\?v\=\w+$/", $youtube_url);
if ($valid) {
    echo "Valid";
} else {
    echo "Invalid";
}
于 2012-11-20T15:11:43.080 に答える
2

URL構文の解析については、このページの他の回答に従いますが、 StackExchange / WebAppsの次の回答で説明するように、 YouTube ID値自体については、もう少し具体的にすることができます。

YouTubeビデオのIDの形式   -https    ://webapps.stackexchange.com/a/101153/141734


ビデオID

videoIdの場合、これは8バイト(64ビット)の整数です。Base64エンコーディングを8バイトのデータに適用するには、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の正規表現(RegEx)はのようになります。

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

チャンネルまたはプレイリストID

channelIdおよびplaylistId文字列は、128ビット(16バイト)の2進整数をBase64でエンコードすることによって生成されます。ここでも、Base64ごとの計算により、観測された22文字の文字列の長さが正しく予測されます。この場合、出力は22 × 6 = 1324ビットの余剰ビットをエンコードできます。これらのゼロは、64個のアルファベット記号のほとんどが最後の位置に表示されるのを制限することになり、4個だけが適格なままになります。すべてのchannelId文字列は、次のいずれかで終わります。

{ A, Q, g, w }

これにより、 channelIdの正規表現が得られます。

[-_A-Za-z0-9]{21}[AQgw]
于 2017-02-01T19:41:20.163 に答える