栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

忽略preg_replace中的html标签

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

忽略preg_replace中的html标签

我假设您应该基于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 resultsforeach($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 >text</span></span><span > that span</span> across a page to search in.    and more <span >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'))


转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/635189.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号