title: PHP BBCode to parse youtube urls
body: <p>I have researched this problem for almost 5hrs now, the best i could come up with is this code from Stackoverflow post:</p>
  
  <pre><code>&lt;?php
  $pattren = '%(?:youtube(?:-nocookie)?\.com/(?:[^/]+/.+/|(?:v|e(?:mbed)?)/|.*[?&amp;]v=)|youtu\.be/)([^"&amp;?/]{11})%i';
  ?&gt;
  </code></pre>
  
  <p>what I want to accomplish is that I have a custom made web forums written by someone else, I want to add the ability to watch YouTube videos directly in forum topics, I tried different codes and patterns the best one is the one I have posted up in this post, it matches pretty much any YouTube link, However there is a single problem i cant overcome with this code, the BBCode tag used in the forum is <code>[yt]youtubelink[/yt]</code>, I tried to prefix the pattern with</p>
  
  <pre><code>&lt;?php
  $pattren = '%\[yt\](?:youtube(?:-nocookie)?\.com/(?:[^/]+/.+/|(?:v|e(?:mbed)?)/|.*[?&amp;]v=)|youtu\.be/)([^"&amp;?/]{11})[\/yt]%i';
  ?&gt;
  </code></pre>
  
  <p>but it just doesn't work there is no error reported whatsoever to indicate there is problem in the pattern</p>
  
  <p>the complete code i used </p>
  
  <pre><code>&lt;?php
  
  $testmessage = "test youtube links [yt]http://www.youtube.com/watch?v=ZCLAwp2HbW4&amp;feature=player_embedded[/yt] more text";
  $pattren1    = '%(?:youtube(?:-nocookie)?\.com/(?:[^/]+/.+/|(?:v|e(?:mbed)?)/|.*[?&amp;]v=)|youtu\.be/)([^"&amp;?/ ]{11})%i';
  $pattren2    = '%\[yt\](?:youtube(?:-nocookie)?\.com/(?:[^/]+/.+/|(?:v|e(?:mbed)?)/|.*[?&amp;]v=)|youtu\.be/)([^"&amp;?/ ]{11})[\/yt]%i';
  
  echo '&lt;h1&gt;works:-&lt;/h1&gt;';
  echo preg_replace($pattren1, '&lt;iframe width="350" height="250" sandbox="" src="http://www.youtube.com/embed/$1" frameborder="0" allowfullscreen&gt;&lt;/iframe&gt;', $testmessage);
  echo '&lt;h1&gt;doesnt work:-&lt;/h1&gt;';
  echo preg_replace($pattren2, '&lt;iframe width="350" height="250" sandbox="" src="http://www.youtube.com/embed/$1" frameborder="0" allowfullscreen&gt;&lt;/iframe&gt;', $testmessage);
  ?&gt; 
  </code></pre>
  
  <p>also while the first pattern partially works it also leaves some URL query string behind for example the first pattern while it does work and get the video ID it leaves this part in the text message <code>&amp;feature=player_embedded</code></p>
  
  <p><strong>UPDATE:</strong></p>
  
  <p>I couldn't get it working with straight up preg_replace, so I came up with different way to fix this issue, I'll post the code and it might be of use for somebody so that he doesn't waste 6hrs of his life on this issue again!</p>
  
  <pre><code>&lt;?php
  $test = "test youtube links [yt]http://www.youtube.com/watch?v=ZCLAwp2HbW4&amp;feature=player_embedded[/yt] more text";
  echo preg_replace_callback('#\[yt\](.*)\[/yt\]#i', function ($matches) {
      $regex = '#(?:youtube(?:-nocookie)?\.com/(?:[^/]+/.+/|(?:v|e(?:mbed)?)/|.*[?&amp;]v=)|youtu\.be/)([^"&amp;?/ ]{11})#i';
          preg_match($regex, $matches[1], $found);
          if ($found[1])
              return '&lt;iframe width="350" height="250" sandbox="" src="http://www.youtube.com/embed/'.$found[1].'" frameborder="0" allowfullscreen&gt;&lt;/iframe&gt;';
  
  }, $test);
  ?&gt;
  </code></pre>
  
  <p>This code works on PHP 5.3 to make it work on &lt; PHP5.3 move the anonymous function to separate function.</p>