如何 忽略 此preg_replace中的 html标签
。我有一个foreach函数来进行搜索,因此,如果有人搜索“苹果范围”,则preg_replace也会将范围应用于范围,并且html会中断:
preg_replace("/($keyword)/i","<span class=\"search_hightlight\">$1</span>",$str);
提前致谢!
我假设您应该基于DOMDocument和DOMXPath而不是使用正则表达式来创建函数。即使那些功能非常强大,您也会遇到像您描述的问题那样的问题,这些问题不是(总是)很容易且不易用正则表达式解决的。
俗话说:不要用正则表达式解析HTML。
记住这是一个好规则,尽管与任何规则一样,它并不总是适用,值得对此下定决心。
XPath允许您查找所有仅包含文本中搜索词的文本,而忽略所有XML元素。
然后,您只需要将这些文本包装到中<span>
就可以了。
编辑: 最后一些代码;)
首先,它利用xpath
来定位包含搜索文本的元素。我的查询看起来像这样,这可能写得更好,我不是超级xpath专业人士:
'//*[contains(., "'.$search.'")]/*[FALSE = contains(., "'.$search.'")]/..'
$search
包含要搜索的文本, 不
包含任何"
(双引号)字符(这会破坏它,如果需要引号。
该查询将返回所有包含textnode的父级,这些node在一起将是一个包含您搜索词的字符串。
由于这样的列表不容易按原样进行进一步处理,因此我创建了一个TextRange
表示DOMText
节点列表的类。对textnode列表进行字符串操作就像将它们当作一个字符串一样有用。
这是例程的基本框架:
$str = '...'; # some XML
$search = 'text that span';
printf("Searching for: (%d) '%s'\n", strlen($search), $search);
$doc = new DOMDocument;
$doc->loadXML($str);
$xp = new DOMXPath($doc);
$anchor = $doc->getElementsByTagName('body')->item(0);
if (!$anchor)
{
throw new Exception('Anchor element not found.');
}
// search elements that contain the search-text
$r = $xp->query('//*[contains(., "'.$search.'")]/*[FALSE = contains(., "'.$search.'")]/..', $anchor);
if (!$r)
{
throw new Exception('XPath failed.');
}
// process search results
foreach($r as $i => $node)
{
$textNodes = $xp->query('.//child::text()', $node);
// extract $search textnode ranges, create fitting nodes if necessary
$range = new TextRange($textNodes);
$ranges = array();
while(FALSE !== $start = strpos($range, $search))
{
$base = $range->split($start);
$range = $base->split(strlen($search));
$ranges[] = $base;
};
// wrap every each matching textnode
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);
}
}
}
对于我的示例XML:
<html>
<body>
This is some <span>text</span> that span across a page to search in.
and more text that span</body>
</html>
它产生以下结果:
<html>
<body>
This is some <span><span class="search_hightlight">text</span></span><span class="search_hightlight"> that span</span> across a page to search in.
and more <span class="search_hightlight">text that span</span></body>
</html>
这表明,这甚至允许查找分布在多个标签中的文本。使用正则表达式根本不是那么容易。
您可以在此处找到完整的代码:(包括TextRange
我从答案示例中摘录的类)。
由于该站点正在使用较旧的LIBXML版本,因此无法在viper键盘上正常工作。它对于我的LIBXML版本20707正常工作。我创建了一个与此问题相关的问题:XPath查询结果顺序。
警告提示:
本示例使用二进制字符串搜索(strpos
)和相关的偏移量,使用DOMText::splitText
函数来分割文本节点。这可能导致错误的偏移量,因为函数需要UTF-8字符偏移量。正确的方法是用于mb_strpos
获取UTF-8
基础值。
该示例仍然有效,因为仅使用与示例数据US-ASCII
具有相同偏移量UTF-8
的示例。
对于现实生活中的情况,该$search
字符串应采用UTF-8编码,而mb_strpos
不应使用strpos
:
while(FALSE !== $start = mb_strpos($range, $search, 0, 'UTF-8'))
问题内容: 我最近看到了很多用于在HTML页面中搜索和突出显示术语的库。但是,我看到的每个库都存在相同的问题,它们找不到部分用html标记封装的文本,并且/或者找不到包含&表示的特殊字符。 示例a: 搜索“测试”将找到第一个实例,但找不到第二个实例。 示例b: 搜索“lápices”或“ lapices”将不会产生结果。 有没有这样做的JS库,或者至少是一种避免这些障碍的方法? 提前致谢! 问题答
问题内容: HTML / CSS中是否有任何内容可以告诉浏览器完全忽略空格? 如此多次,当您想要将两个图像彼此并排放置时-拼命尝试使HTML可读,但是浏览器在它们之间放置了一个空格。 因此,而不是像这样: 你最终得到这个 真是太恐怖了! 问题答案: 哦,您只需一行CSS就可以轻松实现: 劣势,你问?尚无 浏览器实现此 极其有用的功能(通常考虑内联块)。 我有时会做些什么,尽管黑夜很丑,但还是要使用
问题内容: 我收到此错误,因为其中一位用户在他的帖子中添加了 错误:[$ sanitize:badparse]清理程序无法解析以下html块:<3 我写的代码 我想他要采取仅标签和标签 那可能吗? 谢谢! 问题答案: 您可以创建过滤器,以清理HTML。 我在其中使用了strip_tags函数 http://phpjs.org/functions/strip_tags/ 控制器: 视图: http:
有人能帮帮我吗?
问题内容: 我想截断一些文本(从数据库或文本文件加载),但其中包含HTML,因此包含了标签,并且将返回较少的文本。然后,这可能导致标签未关闭或部分关闭(因此Tidy可能无法正常工作,并且内容仍然较少)。我如何基于文本截断(并且可能在到达表时停止,因为这可能会导致更复杂的问题)。 将导致: 我想要的是: 我怎样才能做到这一点? 虽然我的问题是有关如何在PHP中进行操作,但最好知道如何在C#中进行操作
我使用Prometheus push gateway从Cronjob向Prometheus发送指标,然后在Grafana中显示它们。 在cronjob的多次运行过程中,一些指标标签会发生变化。Grafana将这些带有已更改标签的指标显示为单独的指标。如何将具有不同标签值的相同指标合并成一个指标?(Grafana中显示的一行)