Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 如何在preg\u replace或preg\u replace\u回调期间保存对数组的正则表达式反向引用_Php_Regex_Arrays_Preg Replace_Preg Replace Callback - Fatal编程技术网

Php 如何在preg\u replace或preg\u replace\u回调期间保存对数组的正则表达式反向引用

Php 如何在preg\u replace或preg\u replace\u回调期间保存对数组的正则表达式反向引用,php,regex,arrays,preg-replace,preg-replace-callback,Php,Regex,Arrays,Preg Replace,Preg Replace Callback,问题是:我有一个数据库,里面满是用XHTML标记的文章。我们的应用程序用于生成PDF。这其中的一个缺陷是脚注是使用以下模式内联标记的: <p>Some paragraph text<span class="fnt">This is the text of a footnote</span>.</p> $replacer=newendnoter(); $replacer->replace($body); 回声'; 打印($endnotes);//

问题是:我有一个数据库,里面满是用XHTML标记的文章。我们的应用程序用于生成PDF。这其中的一个缺陷是脚注是使用以下模式内联标记的:

<p>Some paragraph text<span class="fnt">This is the text of a footnote</span>.</p>

$replacer=newendnoter();
$replacer->replace($body);
回声';
打印($endnotes);//只是看看$endnotes是否在那里。
回声';
任何指导都会很有帮助,特别是如果有一种更简单的方法可以做到这一点。

首先,最好不要使用正则表达式进行HTML操作;请看这里:

但是,如果您真的想走这条路,那么您的代码有一些地方是错误的:

  • $1
    不是定义的值。您正在查找传入回调的数组,因此需要
    $matches[1]

  • $endnotes
    不是在类外定义的,因此您需要一个getter函数来检索
    $endnotes
    (通常更可取)或者在类中公开变量。用一个getter:

    class Endnoter
    {
        private $number_of_notes = 0;
        private $footnote_texts = array();
    
        public function replace($input) {
    
            return preg_replace_callback('#<span class="fnt">(.*)</span>#i', array($this, 'replace_callback'), $input);
    
        }
    
        protected function replace_callback($matches) {
    
            // the text sits in the matches array
            // see http://php.net/manual/en/function.preg-replace-callback.php
            $this->footnote_texts[] = $matches[1];
    
            return '<sup><a href="#endnote_'.(++$this->number_of_notes).'">'.$this->number_of_notes.'</a></sup>';
    
        }
    
        public function getEndnotes() {
            $out = array();
            $out[] = '<ol>';
    
            foreach($this->footnote_texts as $text) {
                $out[] = '<li>'.$text.'</li>';
            }
    
            $out[] = '</ol>';
    
            return implode("\n", $out);
        }
    
     }
    
  • preg\u replace\u callback
    不通过引用传递,因此实际上没有修改原始字符串<代码>$replacer->replace($body)应该是
    $body=$replacer->replace($body)
    除非您希望通过引用将body传递到
    replace()
    函数中并在其中更新其值

  • 首先,最好不要使用正则表达式进行HTML操作;请看这里:

    但是,如果您真的想走这条路,那么您的代码有一些地方是错误的:

  • $1
    不是定义的值。您正在查找传入回调的数组,因此需要
    $matches[1]

  • $endnotes
    不是在类外定义的,因此您需要一个getter函数来检索
    $endnotes
    (通常更可取)或者在类中公开变量。用一个getter:

    class Endnoter
    {
        private $number_of_notes = 0;
        private $footnote_texts = array();
    
        public function replace($input) {
    
            return preg_replace_callback('#<span class="fnt">(.*)</span>#i', array($this, 'replace_callback'), $input);
    
        }
    
        protected function replace_callback($matches) {
    
            // the text sits in the matches array
            // see http://php.net/manual/en/function.preg-replace-callback.php
            $this->footnote_texts[] = $matches[1];
    
            return '<sup><a href="#endnote_'.(++$this->number_of_notes).'">'.$this->number_of_notes.'</a></sup>';
    
        }
    
        public function getEndnotes() {
            $out = array();
            $out[] = '<ol>';
    
            foreach($this->footnote_texts as $text) {
                $out[] = '<li>'.$text.'</li>';
            }
    
            $out[] = '</ol>';
    
            return implode("\n", $out);
        }
    
     }
    
  • preg\u replace\u callback
    不通过引用传递,因此实际上没有修改原始字符串<代码>$replacer->replace($body)应该是
    $body=$replacer->replace($body)
    除非您希望通过引用将body传递到
    replace()
    函数中并在其中更新其值


  • 我不知道更简单的方法,但你已经走了一半。这似乎奏效了

    我只是稍微整理了一下,在类中移动了变量,并添加了一个输出方法来获取脚注列表

    class Endnoter
    {
    私人$number\u\u票据=0;
    私有$footnote_text=array();
    公共功能替换($input){
    返回preg#u replace_回调('#(.*)#i',数组($this,'replace_callback'),$input);
    }
    受保护的函数替换回调($matches){
    //文本位于matches数组中
    //看http://php.net/manual/en/function.preg-replace-callback.php
    $this->footnote_text[]=$matches[1];
    返回“”;
    }
    公共函数getEndnotes(){
    $out=array();
    $out[]='';
    foreach($this->footnote\u文本为$text){
    $out[]=“
  • ”.$text.“
  • ”; } $out[]=''; 返回内爆(“\n”,$out); } }
    不知道更简单的方法,但你已经成功了一半。这似乎奏效了

    我只是稍微整理了一下,在类中移动了变量,并添加了一个输出方法来获取脚注列表

    class Endnoter
    {
    私人$number\u\u票据=0;
    私有$footnote_text=array();
    公共功能替换($input){
    返回preg#u replace_回调('#(.*)#i',数组($this,'replace_callback'),$input);
    }
    受保护的函数替换回调($matches){
    //文本位于matches数组中
    //看http://php.net/manual/en/function.preg-replace-callback.php
    $this->footnote_text[]=$matches[1];
    返回“”;
    }
    公共函数getEndnotes(){
    $out=array();
    $out[]='';
    foreach($this->footnote\u文本为$text){
    $out[]=“
  • ”.$text.“
  • ”; } $out[]=''; 返回内爆(“\n”,$out); } }
    如果这是另一种语言,我会说是的,有一种更好的方法。在PHP中,我相信答案是否定的,但我可能弄错了。我的想法是,不要调用一个完成整个过程的函数,并给它另一个函数作为参数,而是使用一个循环,在每个循环迭代中只进行一次替换。例如,在Perl中,您可以这样做:
    my$endnote\u no=0;我的@尾注;而($subject=~s!(.*)!!{$endnote_no++;push@endnotes,$1;}
    如果这是另一种语言,我会说是的,有一种更好的方法。在PHP中,我相信答案是否定的,但我可能弄错了。我的想法是,不要调用一个完成整个过程的函数,并给它另一个函数作为参数,而是使用一个循环,在每个循环迭代中只进行一次替换。例如,在Perl中,您可以这样做:
    my$endnote\u no=0;我的@尾注;而($subject=~s!(.*)!!){$endnote_no++;push@endnotes,$1;}
    谢谢@ChicagoRedSox!我想我遵循了你的推理并实现了你的建议,但现在我看到了这个错误:“array_push()期望参数1是array,null给定”;它对源中的每个匹配都重复。感谢您提供有关XML解析的提示——我将尽可能地对此进行研究!您是否将
    $endnotes
    声明为数组(
    private$endnotes=array()
    private$endnotes=[]
    如果您使用的是PHP>=5.4)?您是否将对
    $endnotes
    的调用替换为
    $this->endnotes
    <代码>数组推送($this->endnotes,$matches[1])类中对
    $endnotes
    变量的任何引用都应替换为
    $this->endnotes
    。谢谢@ChicagoRedSox!我想我是听从了你的劝告
    return '<sup><a href="#endnote_' . $this->endnote_no++ . '">' . $this->endnote_no . '</a></sup>';
    
    '<sup><a href="#endnote_1">2</a></sup>';
    
    return '<sup><a href="#endnote_' . ++$this->endnote_no . '">' . $this->endnote_no . '</a></sup>';
    
    array_push($endnotes, $1);
    
    print_r($endnotes);
    
    class Endnotes {
        private $endnotes = array();
        //replace any references to $endnotes in your class with $this->endnotes and add a function:
    
        public function getEndnotes() {
            return $this->endnotes;
        }
    }
    //and then outside
    print_r($replacer->getEndnotes());
    
    class Endnoter
    {
        private $number_of_notes = 0;
        private $footnote_texts = array();
    
        public function replace($input) {
    
            return preg_replace_callback('#<span class="fnt">(.*)</span>#i', array($this, 'replace_callback'), $input);
    
        }
    
        protected function replace_callback($matches) {
    
            // the text sits in the matches array
            // see http://php.net/manual/en/function.preg-replace-callback.php
            $this->footnote_texts[] = $matches[1];
    
            return '<sup><a href="#endnote_'.(++$this->number_of_notes).'">'.$this->number_of_notes.'</a></sup>';
    
        }
    
        public function getEndnotes() {
            $out = array();
            $out[] = '<ol>';
    
            foreach($this->footnote_texts as $text) {
                $out[] = '<li>'.$text.'</li>';
            }
    
            $out[] = '</ol>';
    
            return implode("\n", $out);
        }
    
     }