Preg_replace不会替换所有内容

$content = $this->comment->getContent(true);
$bbcodes = array (
  '#\[cytat=(.*?)\](.*?)\[/cytat\]#' => '<div class="cytata">\\1 napisał/a </div> <div class="cytatb">\\2</div>',
  '#\[cytat\](.*?)\[/cytat\]#' => '<div class="cytata">cytat</div><div class="cytatb">\\1</div>',
);

$content = preg_replace(array_keys($bbcodes), array_values($bbcodes), $content);

That preg_replace is not replacing every tag like that should. For example if there will be only one tag [cytat]some text[/cytat] (cytat means quote in polish) then everything will be ok and the output will be

<div class="cytata">author napisał/a </div> <div class="cytatb">some text</div>                 

but there will be more than a one quote then preg is replacing only one tag, for example

<div class="cytata">o0skar napisał/a </div> <div class="cytatb">[cytat=o0skar]test nr2</div>[/cytat]

thats the output of the double quote, etc. Any ideas? Something wrong?

Maybe I can put preg_replace in while loop, but i dont know if preg_replace returns any variable.

For the sake of regular expressions awesomeness, let's look at this one. I had to change the pattern by 1 character. I removed one of the lazy ? and made this a preg_replace_callback

function pregcallbackfunc($matches){
    $pattern = '#\[cytat=(.*?)\](.*)\[/cytat\]#';
    if(preg_match($pattern, $matches[2])){
        $matches[2] = preg_replace_callback($pattern,'pregcallbackfunc', $matches[2]);
    }
    if($matches[2]){
        return '<div class="cytata">'.$matches[1].' napisał/a </div> <div class="cytatb">'.$matches[2].'</div>';
    }
    return '<div class="cytata">cytat</div><div class="cytatb">'.$matches[1].'</div>';
}

$content = '[cytat=o0skar][cytat=o0skar]test nr2[/cytat][/cytat]';
$content = preg_replace_callback('#\[cytat=(.*?)\](.*)\[/cytat\]#', 'pregcallbackfunc', $content);

Making this recursive will guarantee any level of nested quotes.