2010-11-05 101 views
1

下面的函数将对内容(这是html标记)进行替换,在其找到的关键字的前两次出现时包装粗体和em标签。preg_replace但不匹配如果替换文本出现在标题标签内

但我需要说明的一种情况是,如果关键字已经在h1标签内,我不希望回调发生。

实施例:

< H1>这是一个标题标签的内部的关键字</H1>

后更换

< H1>这是< b>关键字</b>的标题标签内</h1>

我该如何更改替换项,以便跳过显示在标题标签内的关键字(h1-h6)并继续进行下一场比赛?

function doReplace($matches) 
{ 
    static $count = 0; 
    switch($count++) { 
     case 0: return ' <b>'.trim($matches[1]).'</b>'; 
     case 1: return ' <em>'.trim($matches[1]).'</em>'; 
     default: return $matches[1]; 
      } 
    } 

function save_content($content){ 
    $mykeyword = "test"; 
    if ((strpos($content,"<b>".$mykeyword) > -1 || 
    strpos($content,"<strong>".$mykeyword) > -1) && 
    strpos($content,"<em>".$mykeyword) > -1) 
    { 
     return $content; 
    } 
    else 
    { 
     $theContent = preg_replace_callback("/\b(?<!>)($mykeyword)\b/i","doReplace", $content); 
     return $theContent; 
    } 
} 
+1

这可能是适当的:http://stackoverflow.com/questions/1732348/regex-match-open-tags-except- xhtml-self-contained-tags/1732454#1732454 – EboMike 2010-11-05 01:27:14

+3

@EboMike对于标记为[html]和[regex]的问题,99%是合适的:) – alex 2010-11-05 01:29:08

+0

也许我应该使用xpath,但是我找不到xpath示例也做递归查找/替换。 – 2010-11-05 01:35:36

回答

4

不要使用HTML/XML正则表达式:

$d = new DOMDocument(); 
$d->loadHTML($your_html); 
$x = new DOMXpath($d); 
foreach($x->query("//text()[ 
    contains(.,'keyword') 
    and not(ancestor::h1) 
    and not(ancestor::h2) 
    and not(ancestor::h3) 
    and not(ancestor::h4) 
    and not(ancestor::h5) 
    and not(ancestor::h6)]") as $node){ 
    //do with the node as you like 
}  
+0

试图对此进行测试,但我无法获取任何内容{}中的回声。你可以? – 2010-11-05 12:04:07

+0

我在'// text'后面忘了'()',将编辑更改。 – Wrikken 2010-11-05 12:23:14

+0

谢谢! //在查看输出后可以回显什么?尝试echo $ node返回“DOMText类的对象无法转换为字符串” – 2010-11-05 14:38:22