Этот вопрос связан с тем, что я сделал раньше, но поскольку тема закрыта, и мне нужно что-то спросить, я начну новый вопрос, надеясь, что все в порядке.
В моем предыдущем ответе я достаточно упростил проблему и привел к простым, но не полностью работающим решениям. Я понял это в эти дни, когда я выполнял свой код.
Проблема с решениями в предыдущем посте заключается в том, что теги HTML разбиваются на функции замены. Я прочитал во многих сообщениях этого сайта, что мне нужно использовать DOM Parser. Я очень незнакома с этим, и я пробовал код, предложенный пользователем «ircmaxell» в этом сообщении , но это не работает для меня.
Вот пример того, что я сделал:
echo '<style type="text/css"> .ht{ background-color: yellow; } </style>'; /* taken from user ircmaxell at https://stackoverflow.com/questions/4081372/highlight-keywords-in-a-paragraph I just modified line $highlight->setAttribute('class', 'highlight') to $highlight->setAttribute('class', 'ht') and commented the first 2 lines */ function highlight_paragraph($string, $keyword) { //$string = '<p>foo<b>bar</b></p>'; //$keyword = 'foo'; $dom = new DomDocument(); $dom->loadHtml($string); $xpath = new DomXpath($dom); $elements = $xpath->query('//*[contains(.,"'.$keyword.'")]'); foreach ($elements as $element) { foreach ($element->childNodes as $child) { if (!$child instanceof DomText) continue; $fragment = $dom->createDocumentFragment(); $text = $child->textContent; $stubs = array(); while (($pos = stripos($text, $keyword)) !== false) { $fragment->appendChild(new DomText(substr($text, 0, $pos))); $word = substr($text, $pos, strlen($keyword)); $highlight = $dom->createElement('span'); $highlight->appendChild(new DomText($word)); $highlight->setAttribute('class', 'ht'); $fragment->appendChild($highlight); $text = substr($text, $pos + strlen($keyword)); } if (!empty($text)) $fragment->appendChild(new DomText($text)); $element->replaceChild($fragment, $child); } } $string = $dom->saveXml($dom->getElementsByTagName('body')->item(0)->firstChild); return $string; } $string = '<p>This book has been written against a background of both reckless optimism and reckless despair.</p> <p>It holds that Progress and Doom are two sides of the same medal; that both are articles of superstition, not of faith. It was written out of the conviction that it should be possible to discover the hidden mechanics by which all traditional elements of our political and spiritual world were dissolved into a conglomeration where everything seems to have lost specific value, and has become unrecognizable for human comprehension, unusable for human purpose.</p> <p> Hannah Arendt, The Origins of Totalitarianism (New York: Harcourt Brace Jovanovich, Inc., 1973 ed.), p.vii, Preface to the First Edition.</p>'; $keywords = array('This', 'book', 'has', 'been', 'written', 'background', 'reckless', 'optimism', 'despair.', 'holds', 'Progress', 'Doom ', 'two', 'sides', 'medal;', 'articles', 'superstition,', 'faith.', 'lost', 'Arendt,', 'Totalitarianism'); foreach ($keywords as $kw) { $string = highlight_paragraph($string, $kw); } echo $string;
echo $ string возвращает только:
This book has been written against a background of both reckless optimism and reckless despair.
И выделяются только первые два слова: «Это» и «книга».
Обычно он должен выводить всю начальную строку с выделенными ключевыми словами.
Я много искал в stackoverflow и google и не нашел простой в использовании код для достижения моей цели, даже если есть много людей, которые раньше задавали одно и то же.
Мне действительно нужна помощь здесь. Заранее спасибо!
Вам повезло, что мне было очень скучно, когда я увидел этот вопрос. 😉
Код, который вы получили как ответ, похоже, не был протестирован – я не знаю, как он мог работать правильно. Во всяком случае, я устранил все проблемы и представил вам рабочую версию – протестирован на локально установленном Apache Server с PHP 5.3:
function highlight_paragraph($string, $keyword) { $dom = new DOMDocument(); $dom->loadHtml($string); // Search for all text blocks containing the keyword $xpath = new DOMXpath($dom); $textNodes = $xpath->query('//*[contains(.,"'.$keyword.'")]/text()'); foreach ($textNodes as $textNode) { $fragment = $dom->createDocumentFragment(); $text = $textNode->nodeValue; $stubs = array(); while (($pos = stripos($text, $keyword)) !== false) { $fragment->appendChild(new DOMText(substr($text, 0, $pos))); $word = substr($text, $pos, strlen($keyword)); $highlight = $dom->createElement('span'); $highlight->appendChild(new DOMText($word)); $highlight->setAttribute('class', 'ht'); $fragment->appendChild($highlight); $text = substr($text, $pos + strlen($keyword)); } if (!empty($text)) $fragment->appendChild(new DOMText($text)); $textNode->parentNode->replaceChild($fragment, $textNode); } return $dom->saveHTML(); }