preg_replace で HTML タグを除外する方法
提供されたコードは、preg_replace を使用して文字列内の検索結果を強調表示しようとします。ただし、文字列内に HTML タグが存在すると、置換操作で誤ってタグ自体にタグが付けられ、HTML 構造が壊れてしまうため、課題が生じます。
解決策: DOM ベースのアプローチを採用する
正規表現は HTML を解析するための理想的なツールではありません。代わりに、DOM (ドキュメント オブジェクト モデル) と DOMXPath を使用して文字列の XML 構造をナビゲートすることを検討してください。
DOMXPath を使用すると、XML 要素を無視して、特定のテキストを含む要素を検索できます。これにより、関連するテキスト ノードを分離し、目的のスパン タグでラップすることができます。
コードの実装
次のコードは、このアプローチの実装方法を示しています。
$doc = new DOMDocument; $doc->loadXML($str); $xp = new DOMXPath($doc); // Search elements containing the search text $r = $xp->query('//*[contains(., "'.$search.'")]/*[FALSE = contains(., "'.$search.'")]/..', $anchor); // Process search results foreach($r as $i => $node) { // Extract search text nodes and create suitable nodes if necessary $range = new TextRange($xp->query('.//child::text()', $node)); $ranges = array(); while(FALSE !== $start = strpos($range, $search)) { $base = $range->split($start); $range = $base->split(strlen($search)); $ranges[] = $base; }; // Wrap matching text nodes foreach($ranges as $range) { foreach($range->getNodes() as $node) { $span = $doc->createElement('span'); $span->setAttribute('class', 'search_hightlight'); $node = $node->parentNode->replaceChild($span, $node); $span->appendChild($node); } } }
このコードは、検索テキストを含む要素を検索し、それを含まない子要素を無視します。検索領域は TextRange オブジェクトとして表され、一致するテキストの周囲にスパン タグを挿入できます。結果は、HTML 構造を壊すことなく、強調表示された検索結果を含む変更された XML 文字列になります。
以上が構造を壊さずに HTML で検索結果を強調表示するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。