开发者

Regex pregmatch not correct "sometimes"

I have a preg_match_all with a regexpression, that should take a youtube´s video number and place it in the array, so the more youtube videos there is, the more arrays it makes. Here's the result, that are correct:

C1

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

Now, my problem is sometimes this occurs:

C2

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

See the difference? At C1 it takes the video id correct in the ararys and so, the C2 grabs one and then fails and takes the rest in to the array.

The C1 youtube links was like this:

http://www.youtube.com/watch?v=j5-yKhDd64s&feature=email&email=comment_reply_rec开发者_JAVA百科eived 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

The C2 youtube links was like this:

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

the difference is that there is the &feature... in the C1. I think its because my regex isnt fully optimal?

    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; 

How can i fix this? Thank you!


Your regexp:

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

boils down to three alternative parts:

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

The (?<=...) is called a lookbehind assertion and in two of these parts you see it looks for v=.

In the first alternative, it looks for [a-zA-Z0-9-]+ followed by &. (which is a lookahead assertion: (?=...))

The second alternative doesn't apply in this case.

In the third alternative, it looks for anything until hitting & or \n.

Your example doesn't fit correctly on any of those. The easiest fix would be to change the last part:

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

to

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

so it will stop matching on & or any whitespace (\s).

Or a better advice: just rewrite the whole thing to really parse the url in a normal way, saving some headaches in the future.


Following mvds's answer and comments:

$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'];


Edit: this one fishes out any youtube video link, changed it so it stops on whitespace, linebreak or "&"

hope this gives you a start

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜