简体   繁体   中英

How how do I replace the first and last instance in preg replace callback with PHP?

I am creating a custom forum in PHP and CodeIgniter. I am trying to code the bbCode parser, however, I am running into a bit of a problem. I use preg_replace_callback to replace the [quote id=123][/quote] tags. It works fine if there is only one level of quotes, but once I attempt to "nest" quote tags, everything gets thrown off. When a quote tag is parsed, it should replace the first open quote tag and the last close quote tag. Instead, it only parses the first open quote tag and the first close quote tag. Can anyone think of a work-around for this? This is my code:

$str = "[quote id=123][quote id=456]This is the second level[/quote]This is the first level[/quote]";

$str = preg_replace_callback("^\[quote id=([0-9]+)\](.*?)\[/quote\]^", "_parse_quote", $str);

return $str;

function _parse_quote($matches){

        $str = '';

        $CI =& get_instance();

        $query_message = "
                SELECT
                        message_id, author_id, date_posted
                FROM forum_messages
                WHERE message_id = ".$matches[1]."
                LIMIT 1";

        if($query_message = $CI->db->query($query_message)){

                if($query_message->num_rows() > 0){

                        $message = $query_message->row_array();

                        $CI->member->get_info($message['author_id']);
                        $author = $CI->member->info;

                        $str = '
                                <blockquote title="Originally posted by '.$author['display_name'].' about '.timespan(strtotime($message['date_posted']), time()).' ago...">
                                        <p>'.$matches[2].'</p>
                                </blockquote>
                                ';

                }

        }

        return $str;
}

What if you run a regex to first find all the quotes like so:

$str = "[quote id=123][quote id=456]This is the second level[/quote]This is the first level[/quote]";
$quotes = null;
preg_match_all('^\[quote id=([0-9]+)\]^', $str, $quotes);
var_dump($quotes);

With this information you can dynamically generate a specific regex replace for each quote working from inner most to outer most

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM