preg_replace_callback返回与输入相同

时间:2014-04-23 22:06:50

标签: php preg-replace preg-replace-callback

$post = preg_replace_callback("/\[smartquote]((?:(?!\[smartquote\]).)+?)\[\/smartquote\]/s", function($match) use ($pdo){
    if(isset($match[0])){
        $returnData = explode('_',$match[1]);
        if(empty($returnData[0]) || empty($returnData[1])){
            return 'Nothing found';
        } else {
            $getPost = $pdo->prepare("SELECT * FROM `posts` WHERE `tid`=:topic_id && `id`=:id");
                $getPost->bindValue(':topic_id',$returnData[0]);
                $getPost->bindValue(':id',$returnData[1]);
            $getPost->execute();
            if($getPost->rowCount() == 0){
                return '<div class="well"><h5>Quote:</h5><div style="font-size: 12px;">Quote Data</div></div>';
            } else {
                        return 'Something, something, darkside.';   
                }
        }
    }            
},$post);

每当我尝试使用它时,我得到的响应就是输入。有人能帮助我吗?

例如。如果输入$post = '[smartquote]44_12[/smartquote]'; - 它将输出相同的结果。

1 个答案:

答案 0 :(得分:1)

好吧,我尝试了你的代码,它似乎按预期工作,即使我确实看到你在第一个关闭的方括号前面错过了逃脱。我认为这可能会让事情失效,但令我惊讶的是它有效。

以下是我使用的数据:

CREATE TABLE IF NOT EXISTS `posts` (
  `id` int(9) unsigned NOT NULL AUTO_INCREMENT,
  `tid` int(9) unsigned NOT NULL DEFAULT '0',
  `post_title` varchar(100) NOT NULL,
  `post_data` text NOT NULL,
  PRIMARY KEY (`id`),
  KEY `topic_id` (`tid`)
) ENGINE=InnoDB AUTO_INCREMENT=13 DEFAULT CHARSET=latin1;

INSERT INTO `posts` (`id`, `tid`, `post_title`, `post_data`) VALUES
    (12, 44, 'Nan took it', 'There once was a man from Nantucket who kept all his cash in a bucket.');

我拿了你的输入字符串并稍微修改了你的函数,以确保它实际上连接到数据库并从中提取数据。代码如下所示:

$pdo = new PDO("mysql:host=localhost;dbname=so;","root","");

$post = '[smartquote]44_12[/smartquote]';


$post = preg_replace_callback("/\[smartquote]((?:(?!\[smartquote\]).)+?)\[\/smartquote\]/s", function($match) use ($pdo){
    if(isset($match[0])){
        $returnData = explode('_',$match[1]);
        if(empty($returnData[0]) || empty($returnData[1])){
            return 'Nothing found';
        } else {
            $getPost = $pdo->prepare("SELECT * FROM `posts` WHERE `tid`=:topic_id && `id`=:id");
                $getPost->bindValue(':topic_id',$returnData[0]);
                $getPost->bindValue(':id',$returnData[1]);
            $getPost->execute();
            if($getPost->rowCount() == 0){
                return '<div class="well"><h5>Quote:</h5><div style="font-size: 12px;">Quote Data</div></div>';
            } else {
                        //return 'Something, something, darkside.';

                        $row = $getPost->fetchAll();

                        $post_title = $row[0]['post_title'];
                        $post_data = $row[0]['post_data'];

                        $return_data = "<b>".$post_title."</b><br><br>".$post_data;

                        return $return_data;
                }
        }
    }            
}, $post);

print $post;

这输出以下内容:

<b>Nan took it</b><br><br>There once was a man from Nantucket who kept all his cash in a bucket.

无论如何,我的建议是尝试逃避第一个关闭方括号并再试一次。如果数据返回与您输入的数据相同,则可能意味着它无法首先进行匹配。如果确实如此,那么您可以尝试重写表达式,看看是否可以通过其他方式找到匹配。

根据您期望的数据,这可能会有用,并会将主题id存储在$match[1]中,将id存储在$match[2]中:

~(?<=\[smartquote\])(?:(\d+)_(\d+))(?=\[/smartquote\])~s

然后你应该能够完全省略这部分:

if(isset($match[0])){
    $returnData = explode('_',$match[1]);
        if(empty($returnData[0]) || empty($returnData[1])){
        return 'Nothing found';
} else {

如果未设置$match[0],则根本不会运行该功能。不过,您可能仍想检查$match[1]$match[2]是否包含数据。