![](/img/trans.png)
[英]Javascript regexp replace of multiline content between two tags (including the tags)
[英]Javascript RegExp replace text between two tags if the opening tag has specified class
我有以下HTML代码:
<span class="whatever-class custom-class-name" attribute="Whatever 1 AAA">AAA BBB</span>
<span class="search-text custom-class-name" attribute="Whatever 2 AAA">Text AAA</span>
我想替换span标签之间的文本,但是仅当span标签具有类“ search-text ”时才可以 。 因此,就我而言,我有一个包含两个跨度的HTML代码的字符串。 如果它包含搜索到的文本,我想替换第二个跨度中的文本。
我搜索:“ aa ”,我想用<span class="highlight-text">aa</span>
替换它。 因此,最终结果应为:
<span class="whatever-class custom-class-name" attribute="Whatever 1 AAA">AAA BBB</span>
<span class="search-text custom-class-name" attribute="Whatever 2 AAA">Text <span class="highlight-search">AA</span>A</span>
现在我正在做类似的事情:
var paint = $.proxy(this._paint, this);
var regex = /(<span class="search-text[^>]+>|<\/span>)/g;
item.node.innerHTML = item.html.replace(regex, paint);
其中“ value ”是:“ aa ”和“ item.html ”是在我的问题开头出现的HTML。
_paint函数:
_paint: function($0) {
return '<span class="highlight-text">' + $0 + '</span>';
},
这时的结果是第二个跨度被完全包裹在'<span class="highlight-text">' + $0 + '</span>';
。 结果如下:
<span class="whatever-class custom-class-name" attribute="Whatever 1 AAA">AAA BBB</span>
<span class="highlight-text"><span class="search-text custom-class-name" attribute="Whatever 2 AAA">Text AAA</span></span>
我只希望将文本匹配项包装在hghlight跨度内,如下所示:
<span class="whatever-class custom-class-name" attribute="Whatever 1 AAA">AAA BBB</span>
<span class="search-text custom-class-name" attribute="Whatever 2 AAA">Text <span class="highlight-text">AA</span>A</span>
有任何想法吗? 谢谢。
众所周知 ,正则表达式是大多数工作的错误工具。 它是为处理字符串而不是HTML之类的结构化数据而设计的。 幸运的是,您已经在浏览器中,因此您拥有一个为DOM操作设计的完整工具集:也可以使用它。 (您还用jQuery标记了问题,这使它变得更加容易。)
更新:我会误解问题的详细信息,并且是从父节点的属性中而不是从外部拉出搜索字符串。 我也未能使搜索不区分大小写。 现在都在以下内容中进行了更正:
// Make a case-insensitive regex from the search string let str = 'aa'; let re = new RegExp(str, "gi"); // operate only on the .search-text nodes: $('.search-text').each(function(i, el) { // get the current contents of the element: let text = $(el).html(); // Add your highlights: text = text.replace(re, '<span class="highlight-text">$&</span>'); // insert the modified text back into the DOM: $(el).html(text); })
.highlight-text { background-color: #FFC }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <span class="whatever-class custom-class-name" attribute="Whatever 1 AAA">AAA BBB</span> <span class="search-text custom-class-name" attribute="Whatever 2 AAA">Text AAA</span> I
仅当.search-text
元素没有子节点时,这才是真正安全的。 即使它们包含一些HTML,它通常也可以工作,但前提是:
.search-text
Wholesale的内容。) 例如,尝试在包含<span>
元素的html字符串中突出显示单词“ span”会导致无效的html:
// same script as above $('.search-text').each(function(i, el) { let text = $(el).html(); let highlights = $(el).attr("attribute").split(" "); for (str of highlights) { text = text.replace(str, '<span class="highlight-text">' + str + '</span>'); } $(el).html(text); })
.highlight-text { background-color: #FFC }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <span class="search-text" attribute="span">Text AAA <span>test</span></span>
如果您的起点是HTML字符串而不是已经构建的DOM树,那么您要做的就是首先将该字符串转换为文档片段,以便可以在其上使用以下DOM工具:
let fragment = $('<template>');
fragment.html($yourStringHere);
/* manipulate fragment contents as above, then */
return fragment.html();
受Daniel Beck的答案启发的部分解决方案。 此解决方案不操纵DOM。 (我只是将结果显示在DOM上以进行演示)
https://jsfiddle.net/mt2yz90L/3/
HTML:
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="result">
</div>
JS:
let searchedText = 'aa';
let html ='<span class="whatever-class custom-class-name" attribute="Whatever 1 AAA">AAA BBB</span><span class="search-text custom-class-name" attribute="Whatever 2 AAA">Text AAA</span> I';
var htmlParts = html.split(/(<span class="search-text[^>]+>|<\/span>)/g);
var htmlPartsIndex = 0;
for(var i=0; i < htmlParts.length; i++) {
if(htmlParts[i].indexOf('search-text') !== -1) {
htmlPartsIndex = ++i;
break;
}
}
if(htmlPartsIndex > 0) {
htmlParts[htmlPartsIndex] = htmlParts[htmlPartsIndex].toLowerCase().replace(searchedText, '<span class="highlight-text">' + searchedText + '</span>')
}
$('#result').html(htmlParts.join(''));
CSS:
.highlight-text {
background-color: red;
}
我唯一的问题是,就我而言(要解析的项目超过300个),它阻止了浏览器。 所以这很慢。 我发布它的想法是,也许有人会分享更快的解决方案。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.