2014-09-29 30 views
0

尝试编写一个函数,它将在任何字符串中替换#something#和#anything#,其中的项目与我的db中与“something”和“anything”名称匹配的项目。替换字符串中的标记之间的多个项目

这应该适用于我的字符串中有多少不同的#some-name#。下面是我到目前为止的工作,虽然只有最后一个(#anything#)被我的浏览器加载时被替换为正确的代码。

请记住,我正在学习,所以我可能会完全关闭如何去做这件事。如果有更好的方法,我全都是耳朵。

HTML(字符串)

<p>This is "#something#" I wanted to replace with code from my database. Really, I could have "#anything#" between my pound sign tags and it should be replaced with text from my database</p> 

OUTPUT我越来越

This is "#something#" I want to replace with code from my database. Really, I could have "Any Name" between my pound sign tags and it should be replaced with text from my database 

所需的输出

This is "The Code" I want to replace with code from my database. Really, I could have "Any Name" between my pound sign tags and it should be replaced with text from my database 

功能CMS类a.php只会

public function get_snippets($string) { 
$regex = "/#(.*?)#/"; 
preg_match_all($regex, $string, $names); 
$names = $names[1]; 
    foreach ($names as $name){ 
    $find_record = Snippet::find_snippet_code($name); 
    $db_name = $find_record->name; 
    if($name == $db_name) { 
    $snippet_name = "/#".$name."#/"; 
    $code = $find_record->code; 
    } 
    } 
echo preg_replace($snippet_name, $code, $string); 
} 

函数摘录类b.php

public static function find_snippet_code($name) { 
global $database; 
$result_array = static::find_by_sql("SELECT * from ".static::$table_name." WHERE name = '{$name}'"); 
return !empty($result_array) ? array_shift($result_array) : false; 
} 

回答

0

这是因为发生foreach()循环之外你preg_replace,所以它只会发生一次。 这是一个基于你的代码的实例,它返回$string

注意,我还使用PREG_SET_ORDER这给了我每场比赛作为自己的数组:

function get_snippets($string) { 
    $regex = '/#([^#]+)#/'; 
    $num_matches = preg_match_all($regex, $string, $matches, PREG_SET_ORDER); 
    if ($num_matches > 0) { 
     foreach ($matches as $match) { 
      // Each match is an array consisting of the token we matched and the 'name' without the special characters 
      list($token, $name) = $match; 

      // See if there is a matching record for 'name' 
      $find_record = Snippet::find_snippet_code($name); 

      // This step might be redundant, but compare name with the record name 
      if ($find_record->name == $name) { 
       // Replace all instances of #token# with the code from the matched record 
       $string = preg_replace('/'.$token.'/', $find_record->code, $string); 
      } 

     } 
    } 

    return $string; 
} 
+0

太棒了!现在我只需要了解这一点。问题,你说这是因为我的preg_replace超出了我的foreach()循环。当我在foreach()循环中测试它时,它甚至做了更疯狂的事情。那是唯一错误的,必须有别的东西,不是? – user2998254 2014-09-29 05:03:24

+0

在您的版本中,每次更换时都使用'echo()'。在我提供的版本中,我们直接在'$ string'上工作,它是传递给函数的副本。这就是在循环内导致奇怪输出的差异。 – itsmejodie 2014-09-29 05:18:13

0

你要寻找的是preg_replace_callback()

public function get_snippets($string) 
{ 
    $regex = "/#(.*?)#/"; 
    return preg_replace_callback($regex, function($match) { 
     $find_record = Snippet::find_snippet_code($match[1]); 
     return $find_record === false ? '' : $find_record->code; 
    }, $string); 
} 
+0

感谢您的回复,但这段代码对我来说并不适用。 – user2998254 2014-09-29 05:11:02

相关问题