1

出力を送信する前に処理することにより、検索された単語をサーバー側で強調表示したいと考えています。

「サーバー側」の背後にある理由は次のとおりです。

1) Unicode テキストの Javascript の強調表示がひどい。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: OPEN と CLOSE という単語で囲まれていない特定の単語のすべての出現を置き換えるで、いくつかの同様のことを見ましたか? しかし、これを私の要件に合わせる方法がわかりません。

4

2 に答える 2

2

正規表現で HTML を解析しようとしないでください。HTML パーサーを使用してください。

正規表現を使用してアンカー タグを壊さずに PHP で検索語を強調表示するを参照してください。正規表現は 、XHTML の自己完結型タグを除く開始タグに一致します。

于 2013-03-18T08:08:20.320 に答える
0

実際、HTML に正規表現を使用するのは良くない考えであることは誰もが知っていますが、この場合、< ... > の外側にあるテキストを置き換えたいだけなので、実際には DOM は必要ありません。

この解決策は私にとってはうまくいくようです:

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;
}

みんなに感謝します。

于 2013-03-18T17:14:40.433 に答える