代码之家  ›  专栏  ›  技术社区  ›  mattalxndr

在文本中插入多个链接,忽略恰好插入的匹配项

  •  1
  • mattalxndr  · 技术社区  · 15 年前

    我正在工作的站点有一个数据库表,其中充满了词汇表术语。我正在构建一个函数,它将使用一些HTML并用工具提示链接替换词汇表术语的第一个实例。

    我想底线是,我需要忽略文本,如果它:

    • 出现在 < >
    • 出现在 <a></a> 标签。

    这是我目前掌握的情况。我希望有人能想出一个聪明的解决办法。

    function insertGlossaryLinks($html)
    {
        // Get glossary terms from database, once per request
        static $terms;
        if (is_null($terms)) {
            $query = Doctrine_Query::create()
                ->select('gt.title, gt.alternate_spellings, gt.description')
                ->from('GlossaryTerm gt');
            $glossaryTerms = $query->rows();
    
            // Create whole list in $terms, including alternate spellings
            $terms = array();
            foreach ($glossaryTerms as $glossaryTerm) {
    
                // Initialize with title
                $term = array(
                    'wordsHtml' => array(
                        h(trim($glossaryTerm['title']))
                        ),
                    'descriptionHtml' => h($glossaryTerm['description'])
                    );
    
                // Add alternate spellings
                foreach (explode(',', $glossaryTerm['alternate_spellings']) as $alternateSpelling) {
                    $alternateSpelling = h(trim($alternateSpelling));
                    if (empty($alternateSpelling)) {
                        continue;
                    }
                    $term['wordsHtml'][] = $alternateSpelling;
                }
    
                $terms[] = $term;
            }
        }
    
        // Do replacements on this HTML
        $newHtml = $html;
        foreach ($terms as $term) {
            $callback = create_function('$m', 'return \'<a href="javascript:void(0);" class="glossary-term" title="'.$term['descriptionHtml'].'"><span>\'.$m[0].\'</span></a>\';');
            $term['wordsHtmlPreg'] = array_map('preg_quote', $term['wordsHtml']);
            $pattern = '/\b('.implode('|', $term['wordsHtmlPreg']).')\b/i';
            $newHtml = preg_replace_callback($pattern, $callback, $newHtml, 1);
        }
    
        return $newHtml;
    }
    
    2 回复  |  直到 15 年前
        1
  •  1
  •   Chris Laplante    15 年前

    使用regex来处理HTML总是有风险的。您将花费很长时间来摆弄您的正则表达式的贪婪和懒惰,以便只捕获不在标记中的文本,而不捕获标记名本身中的文本。我的建议是抛弃当前使用的方法,使用HTML解析器解析HTML,如下所示: http://simplehtmldom.sourceforge.net/ . 我以前用过,也向别人推荐过。它是处理复杂HTML的一种简单得多的方法。

        2
  •  0
  •   mattalxndr    15 年前

    工作太好了!

    推荐文章