替换字符串中的标记之间的多个项目

时间:2014-09-29 03:36:22

标签: php preg-replace preg-match

尝试编写一个函数,用任何字符串中的#something#和#anything#替换我的db中与名称相匹配的项目""和"任何事情"。

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

请记住我正在学习,所以我可能完全不知道如何解决这个问题。如果有更好的方法,我全都耳朵。

HTML(String)

<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>

输出我正在

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);
}

Snippet类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;
}

2 个答案:

答案 0 :(得分:0)

这是因为您的preg_replace发生在foreach()循环之外,所以它只发生一次。 这是一个基于您的代码的工作示例,它返回$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;
}

答案 1 :(得分: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);
}