正则表达式preg_match不正确“有时”

时间:2011-01-01 13:55:28

标签: php regex preg-match-all

我有一个带有重复播放的preg_match_all,它应该取一个youtube的视频编号并将其放在数组中,因此视频的视频越多,它产生的阵列就越多。这是结果,这是正确的:

C1

Array ( [0] => j5-yKhDd64s ) 1Array ( [0] => j5-yKhDd64s ) 1Array ( [0] => j5-yKhDd64s ) 1 

现在,我的问题有时会发生:

C2

Array ( [0] => _dKtoRU7Tlk http://www.youtube.com/watch?v=_dKtoRU7Tlk http://www.youtube.com/watch?v=_dKtoRU7Tlk ) 1 

看到区别?在 C1 时,它会在ararys中获取正确的视频ID,因此, C2 会抓取一个然后失败并将其余部分放入数组中。

C1 youtube链接如下:

  

http://www.youtube.com/watch?v=j5-yKhDd64s&feature=email&email=comment_reply_received   http://www.youtube.com/watch?v=j5-yKhDd64s&feature=email&email=comment_reply_received   http://www.youtube.com/watch?v=j5-yKhDd64s&feature=email&email=comment_reply_received

C2 youtube链接如下:

  

http://www.youtube.com/watch?v=_dKtoRU7Tlk   http://www.youtube.com/watch?v=_dKtoRU7Tlk   http://www.youtube.com/watch?v=_dKtoRU7Tlk

区别在于 C1 中有&功能....我认为这是因为我的正则表达不是完全最优的?

    if (preg_match_all("#(?<=v=)[a-zA-Z0-9-]+(?=&)|(?<=[0-9]/)[^&\n]+|(?<=v=)[^&\n]+#", $content, $matches, PREG_SET_ORDER)) {
      foreach($matches as $m) {
   echo print_r($m);
      }
    }
    $nContent = preg_replace("#(?:https?://)?(?:www\.)?youtube\.com/(?:[^\s]*)#", '', $content);
    echo $nContent; 

我该如何解决这个问题?谢谢!

3 个答案:

答案 0 :(得分:3)

你的正则表达式:

#(?<=v=)[a-zA-Z0-9-]+(?=&)|(?<=[0-9]/)[^&\n]+|(?<=v=)[^&\n]+#

归结为三个替代部分:

(?<=v=)[a-zA-Z0-9-]+(?=&)
(?<=[0-9]/)[^&\n]+
(?<=v=)[^&\n]+

(?<=...)被称为lookbehind断言,在其中两个部分中,您会看到v=

在第一种方案中,它会查找[a-zA-Z0-9-]+,然后是&。 (这是一个先行断言:(?=...)

第二种选择在这种情况下不适用。

在第三种方案中,它会在点击&\n之前查找任何内容。

您的示例不适合其中任何一个。最简单的解决方法是更改​​最后一部分:

(?<=v=)[^&\n]+

(?<=v=)[^&\s]+

因此它会停止在&或任何空格(\s)上进行匹配。

或者更好的建议:只需重写整个内容,以正常的方式真正解析网址,将来可以避免一些麻烦。

答案 1 :(得分:2)

关注mvds的回答和评论:

$parsed_url = parse_url("http://www.youtube.com/watch?v=j5-yKhDd64s&feature=email&email=comment_reply_received");
parse_str($parsed_url["query"],$output);
echo $output['v'];

答案 2 :(得分:0)

编辑:这个可以播放任何youtube视频链接, 改变它所以它停止在空白,换行或“&amp;”

希望这能给你一个开始

"{youtube.com/watch[?]v=([a-z0-9_-]*?)[^&\s]+}i"