Php 如何在preg\u replace或preg\u replace\u回调期间保存对数组的正则表达式反向引用
问题是:我有一个数据库,里面满是用XHTML标记的文章。我们的应用程序用于生成PDF。这其中的一个缺陷是脚注是使用以下模式内联标记的: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);//
<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()
函数中并在其中更新其值$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);
}
}