我需要搜索一些内容并用HTML包含某些单词。要搜索的单词是在一个数组中,我想只替换每组匹配的第二个到最后一个匹配项。所以,作为一个例子,如果有5场比赛,我想替换第4场比赛。如果有3场比赛,请更换第2场比赛。如果有2个匹配项,则替换第2个/最后一个匹配项,如果只有一个匹配项,则使用该匹配项。
回调函数在使用回调的函数外部。
我认为我需要一个数组计数 - 减去一个 - 然后将该数字传递给回调函数并在那里使用它,但也许有更简单的方法吗?
简化的功能是:
function repWords($content) {
foreach ($words_array as $w) {
$content = preg_replace_callback('/\b('.$w.'[s]?)\b/S', array(&$this,'addHtml'), $content);
}
return $content;
}
function addHtml($format){
return '<span>' . $format[1] . '</span>'
}
这可以根据需要替换它找到的所有单词,我可以将其设置为随机替换一些,但我想 替换 nth 发生和/或仅替换一个事件(并不总是第一次出现)。
答案 0 :(得分:1)
根据您的要求,我想出了以下内容:
// needs to be global given that you are using non-anonymous function syntax
$count = 0;
function repWords($content) {
global $count;
$words_array = array('some','content','foobar');
foreach ($words_array as $w) {
$pattern = '~\b('.$w.'s?)\b~';
$count=0;
preg_match_all($pattern,$content,$matches);
$count=count($matches[0]);
if ($count>0)
$content = preg_replace_callback($pattern,'addHtml',$content);
}
return $content;
}
function addHtml ($format) {
global $count;
static $cc=1;
static $pf='';
$val=$format[1];
$cc = ($pf!=$val) ? 1 : ++$cc;
if ((1==$count)||($cc==($count-1)))
$format[1]= '<span>' . $val . '</span>';
$pf=$val;
return $format[1];
}
$content = <<<EOC
this is some content
some more content
this content foobar
EOC;
echo repWords($content);
<强>输出强>
this is <span>some</span> content
some more <span>content</span>
this content <span>foobar</span>
注意:这会使用全局变量$count
。一般来说,使用全局变量是个坏主意。但是,当您选择单独定义回调而不是使用匿名函数时,由于php和preg_replace_callback
(或任何可以指定回调的函数)的限制,这是少数几个被勉强接受的示例之一。如果您使用的是php5.3 +并且愿意使addHtml
成为匿名函数,则可以使用$count
将use
传递给匿名函数。或者,如果所有这些实际上都在一个类中,则将其设为类属性并使用$this->count
代替。
另一个注意事项:你说的最后一件事是“(并非总是第一次出现)”我对此感到有些困惑并认为可能意味着你想以某种方式指明 nth *而不是它始终是“倒数第二个(或者如果只有1个则是第一个”,例如在我的代码示例中,您可能希望将其更改为每个第3个到第3个字而不是第2个到最后一个字我请你澄清,但是当我发布这个解决方案时你没有回复,所以我没有编写代码以便灵活处理。但是,希望你能够采取这个并改变它以适合你这就是你想要的。基本上它将涉及将另一个arg传递给repWords
,它还将涉及使用另一个全局变量在addHtml
中使用,其中使用$cc==($count-1)
。