我正在尝试使用正则表达式验证Youtube网址:
preg_match('~http://youtube.com/watch\?v=[a-zA-Z0-9-]+~', $videoLink)
它有点工作,但它可以匹配格式错误的URL。例如,这将匹配ok:
http://www.youtube.com/watch?v=Zu4WXiPRek
但是这样:
http://www.youtube.com/watch?v=Zu4WX£&P!ek
这不会:
http://www.youtube.com/watch?v=!Zu4WX£&P4ek
我认为这是因为+
运算符。它与v=
之后的第一个字符相匹配,当它需要尝试匹配v=
后面的所有内容与[a-zA-Z0-9-]
时。感谢任何帮助。谢谢。
答案 0 :(得分:3)
提供比正则表达式更大且更不优雅的替代方案,但与PHP的本机URL解析函数一起使用,因此从长远来看它可能更可靠:
$url = "http://www.youtube.com/watch?v=Zu4WXiPRek";
$query_string = parse_url($url, PHP_URL_QUERY); // v=Zu4WXiPRek
$query_string_parsed = array();
parse_str($query_string, $query_string_parsed); // an array with all GET params
echo($query_string_parsed["v"]); // Will output Zu4WXiPRek that you can then
// validate for [a-zA-Z0-9] using a regex
答案 1 :(得分:0)
问题是您不需要在URL的v =部分中使用任何特定数量的字符。所以,例如,检查
http://www.youtube.com/watch?v=Zu4WX£&P!ek
将匹配
http://www.youtube.com/watch?v=Zu4WX
因此返回true。您需要在v = part中指定所需的字符数:
preg_match('~http://youtube.com/watch\?v=[a-zA-Z0-9-]{10}~', $videoLink)
或指定组[a-zA-Z0-9-]必须是字符串的最后一部分:
preg_match('~http://youtube.com/watch\?v=[a-zA-Z0-9-]+$~', $videoLink)
你的另一个例子
http://www.youtube.com/watch?v=!Zu4WX£&P4ek
不匹配,因为+符号要求至少一个字符必须与[a-zA-Z0-9 - ]匹配。
答案 2 :(得分:0)
简短回答:
preg_match('%(http://www.youtube.com/watch\?v=(?:[a-zA-Z0-9-])+)(?:[&"\'\s])%', $videoLink)
这里有一些假设,让我解释一下:
( ... )
部分添加了一个捕获组http://www.youtube.com/watch?v=blah
,以便我们可以说“我希望获得整个经过验证的链接,包括?v = movieHash”< / LI>
(?: ... )
周围添加了非捕获组[a-zA-Z0-9-]
,并在其外部留下了+号。这将允许我们将所有允许的字符匹配到某个点。最重要的是,您需要告诉它您期望您的链接是如何终止的。我用(?:[&"\'\s])
?)是否采用html格式(例如锚标签)?如果是这样, href 中的链接显然会以“或'结束。
?)或者查询字符串可能还有更多内容,因此在 v 的值之后会有&amp; 。
?)链接结束后可能有空格或换行符 \ s 。
重要的一点是,如果您知道正在搜索的内容,那么您可以获得更准确的结果,就像许多正则表达式一样。
这个非捕获组(我正在为你做出假设)会在你关心的事情之后找到并忽略所有额外的垃圾(?v = awesomeMovieHash)
结果:
http://www.youtube.com/watch?v=Zu4WXiPRek
- Group 1 contains the http://www.youtube.com/watch?v=Zu4WXiPRek
http://www.youtube.com/watch?v=Zu4WX&a=b
- Group 1 contains http://www.youtube.com/watch?v=Zu4WX
http://www.youtube.com/watch?v=!Zu4WX£&P4ek
- No match
a href="http://www.youtube.com/watch?v=Zu4WX&size=large"
- Group 1 contains http://www.youtube.com/watch?v=Zu4WX
http://www.youtube.com/watch?v=Zu4WX£&P!ek
- No match
答案 3 :(得分:0)
“v = ...”blob不能保证是URL查询部分的第一个参数。我建议使用PHP的parse_url()函数将URL分解为其组成部分。如果有人以“https://”开头,或者只是使用“youtube.com”代替“www.youtube.com”等,您也可以重新组合原始网址。
function get_youtube_vidid ($url) {
$vidid = false;
$valid_schemes = array ('http', 'https');
$valid_hosts = array ('www.youtube.com', 'youtube.com');
$valid_paths = array ('/watch');
$bits = parse_url ($url);
if (! is_array ($bits)) {
return false;
}
if (! (array_key_exists ('scheme', $bits)
and array_key_exists ('host', $bits)
and array_key_exists ('path', $bits)
and array_key_exists ('query', $bits))) {
return false;
}
if (! in_array ($bits['scheme'], $valid_schemes)) {
return false;
}
if (! in_array ($bits['host'], $valid_hosts)) {
return false;
}
if (! in_array ($bits['path'], $valid_paths)) {
return false;
}
$querypairs = explode ('&', $bits['query']);
if (count ($querypairs) < 1) {
return false;
}
foreach ($querypairs as $querypair) {
list ($key, $value) = explode ('=', $querypair);
if ($key == 'v') {
if (preg_match ('/^[a-zA-Z0-9\-_]+$/', $value)) {
# Set the return value
$vidid = $value;
}
}
}
return $vidid;
}
答案 4 :(得分:0)
以下正则表达式将匹配任何youtube链接:
$pattern='@(((http(s)?://(www\.)?)|(www\.)|\s)(youtu\.be|youtube\.com)/(embed/|v/|watch(\?v=|\?.+&v=|/))?([a-zA-Z0-9._\/~#&=;%+?-\!]+))@si';