2013-03-18 46 views
1

我想通过在发送输出之前处理输出来执行搜索字的服务器端突出显示。我想要替换所有没有包含在内的字符串< ... >

后面 “服务器端” 的理由是:

1)投票高亮Unicode文本很烂。 2)\ b不使用unicode(至少在JS,AFAIK中)。 3)JS中没有后援支持。

我正在使用下面的功能,但昨晚意识到,第一部分被写入跳过< ...>不工作。

public function ss_highlight($terms, $buf) 
{ 
    if (empty($terms)) { 
     return $buf;; 
    } 

    /* sort before using length for better match */ 
    usort($terms, function($a, $b) { 
     return mb_strlen($b) - mb_strlen($a); 
    }); 
    $str_terms = implode('|', $terms); 

    /* server side highlighter */ 
    $buf = preg_replace('/(<[^>]+>)*(?<=[\s|:|\-|>|\(|\)|\.|,|\/|^])('.$str_terms.')(?=[\s|:|\-|<|\(|\)|\.|,|\/]|$)/i', '$1<span class="highlight">$2</span>', $buf); 

    return $buf; 
} 

任何想法,将不胜感激。

问候。 PS:我在Replacing all occurences of a specific word which are not enclosed with the words OPEN and CLOSE?中看到过一些类似的东西,但无法弄清楚如何使这符合我的要求。

回答

0

其实,大家都知道使用正则表达式的HTML是一个坏主意,但在这种情况下,我们真的不需要DOM,因为我们只是想取代任何外界一些文字aoccuring < ...>。

该解决方案似乎为我工作的罚款:

public function ss_highlight($terms, $buf) 
{ 
    if (empty($terms)) { 
     return $buf;; 
    } 

    /* sort before using length for better match */ 
    usort($terms, function($a, $b) { 
     return mb_strlen($b) - mb_strlen($a); 
    }); 
    $str_terms = implode('|', $terms); 

    /* server side highlighter */ 
    $buf = preg_replace_callback('#((?:(?!<[/a-z]).)*)([^>]*>|$)#si', 
         function ($matches) use ($str_terms) { 
          //return preg_replace('/(?<=[\s:\-\>\(\)\.,\/^])('.$str_terms.')(?=[\s:\-\<\(\)\.,\/]|$)/i', '<span class="highlight">$1</span>', $matches[1]).$matches[2]; 
          return preg_replace('/(?<!\pL)('.$str_terms.')(?!\pL)/i', '<span class="highlight">$1</span>', $matches[1]).$matches[2]; 
         }, $buf); 

    return $buf; 
} 

感谢大家。

相关问题