提问者:小点点

在数组上使用时发生PHP preg_replace错误


我们有一个网络应用程序,它用str_replace()替换一些文本。查找字符串和替换字符串存储在模板文件中。

我们需要将str_replace()函数替换为preg_replace(),以便能够在find字符串中使用regex(在同一模板文件中设置它们)。

在原始脚本中,我们有这样的php代码部分。

在一个文件中:

类SiteConfig{

// Strings to search for in HTML before processing begins (used with $replace_string)
public $find_string = array();
// Strings to replace those found in $find_string before HTML processing begins
public $replace_string = array();

// a lot of code goes here

public function append(SiteConfig $newconfig) {
    foreach (array('find_string', 'replace_string') as $var) {
        // append array elements for this config variable from $newconfig to this config
        //$this->$var = $this->$var + $newconfig->$var;
        $this->$var = array_merge($this->$var, $newconfig->$var);
    }
}

// a lot of code goes here

public static function build_from_array(array $lines) {
    $config = new SiteConfig();
    foreach ($lines as $line) {
        $line = trim($line);

        // skip comments, empty lines
        if ($line == '' || $line[0] == '#') continue;

        // get command
        $command = explode(':', $line, 2);
        // if there's no colon ':', skip this line
        if (count($command) != 2) continue;
        $val = trim($command[1]);
        $command = trim($command[0]);
        //if ($command == '' || $val == '') continue;
        // $val can be empty, e.g. replace_string: 
        if ($command == '') continue;

        // strip_attr is now an alias for strip.
        // In FTR 3.8 we can strip attributes from elements, not only the elements themselves
        // e.g. strip: //img/@srcset (removes srcset attribute from all img elements)
        // but for backward compatibility (to avoid errors with new config files + old version of FTR)
        // we've introduced strip_attr and we'll recommend using that in our public site config rep.
        // strip_attr: //img/@srcset
        if ($command == 'strip_attr') $command = 'strip';

        // check for commands where we accept multiple statements
        if (in_array($command, array('title', 'body', 'author', 'date', 'strip', 'strip_id_or_class', 'strip_image_src', 'single_page_link', 'single_page_link_in_feed', 'next_page_link', 'native_ad_clue', 'http_header', 'test_url', 'find_string', 'replace_string'))) {
            array_push($config->$command, $val);
        // check for single statement commands that evaluate to true or false
        } elseif (in_array($command, array('tidy', 'prune', 'autodetect_on_failure', 'insert_detected_image'))) {
            $config->$command = ($val == 'yes');
        // check for single statement commands stored as strings
        } elseif (in_array($command, array('parser'))) {
            $config->$command = $val;
        // special treatment for test_contains
        } elseif (in_array($command, array('test_contains'))) {
            $config->add_test_contains($val);
        // special treatment for if_page_contains
        } elseif (in_array($command, array('if_page_contains'))) {
            $config->add_if_page_contains_condition($val);
        // check for replace_string(find): replace
        } elseif ((substr($command, -1) == ')') && preg_match('!^([a-z0-9_]+)\((.*?)\)$!i', $command, $match)) {
            if (in_array($match[1], array('replace_string'))) {
                array_push($config->find_string, $match[2]);
                array_push($config->replace_string, $val);
            } elseif (in_array($match[1], array('http_header'))) {
                $_header = strtolower(trim($match[2]));
                $config->http_header[$_header] = $val;
            }
        }
    }
    return $config;
}

}

在另一个文件中:

public function process($html, $url, $smart_tidy=true) {

    // a lot of code goes before

    // do string replacements
    if (!empty($this->config->find_string)) {
        if (count($this->config->find_string) == count($this->config->replace_string)) {
            $html = str_replace($this->config->find_string, $this->config->replace_string, $html, $_count);
            $this->debug("Strings replaced: $_count (find_string and/or replace_string)");
        } else {
            $this->debug('Skipped string replacement - incorrect number of find-replace strings in site config');
        }
        unset($_count);
    }

    // a lot of code goes after
}

我试图用preg_replace替换str_replace(),但在测试时显示错误:

警告:preg_replace():没有结尾匹配分隔符

            $html = preg_replace($this->config->find_string, $this->config->replace_string, $html, $_count);

错误在哪里?如何将str_replace()函数正确替换为preg_replace()?我对php非常了解,所以非常需要任何帮助。非常感谢!


共1个答案

匿名用户

像这样重写过程函数:

public function process($html, $url, $smart_tidy=true) {

    // a lot of code goes before

    // do string replacements
    if (!empty($this->config->find_string)) {
        if (count($this->config->find_string) == count($this->config->replace_string)) {



    $new_config_find_string = array_map(function($new_pattern)
    {
        return '/'.preg_quote($new_pattern).'/';
    },$this->config->find_string);


    $html = preg_replace($new_config_find_string, $this->config->replace_string, $html, $_count);

            $this->debug("Strings replaced: $_count (find_string and/or replace_string)");
        } else {
            $this->debug('Skipped string replacement - incorrect number of find-replace strings in site config');
        }
        unset($_count);
    }

    // a lot of code goes after
}