繁体   English   中英

使用正则表达式从搜索中排除 HTML 标签而不删除 HTML 标签?

[英]Using Regex to exclude HTML tags from the search without deleting the HTML tags?

在对这个问题进行了先前的研究后, 我知道这不是一个很好的方法,但我为一家截止日期很短且质量......没有真正讨论过的公司工作。 如果这在 100 次中有 95 次有效,那就没问题了。 找出解析器不在时间预算之内。 我也是初级开发者,高级开发者放弃了这个项目,所以我的技能水平不高,我明天需要这个。

我还找到了很多从文本选择中删除标签的解决方案,但我也不能这样做,因为另一个 API 稍后会使用修改后的文本将其吐出到网页上。 HTML 标签必须保留。

我目前正在使用它来查找我想要在 HTML 中的单词。 有没有办法可以使用正则表达式来修改它以不包含属于 HTML 标签/是 HTML 标签的单词?

const reText = new RegExp(text, 'gi');
htmlPile = htmlPile.replace(reText, ‘<span>‘ + text + ‘</span>‘);

我假设我可以以某种方式修改text ,但我该怎么做? 因此,如果说text === 'span'我如何确保它不包含 span 标签,或者在<>中不包含任何其他单词?

我只需要 100 个解决方案中的 95 个。

样本输入:

<span class=“span”>span</span> 

期望的输出:

<span class=“span”><span class=“formatting”>span</span></span>

是的,不要使用 RegExp 来操作 HTML。

您的任务只不过是将直接Node.childNodesnodeType 3 )包装到<span class="formatted">
对于该任务,您可能希望在确保仅在该特定 nodeType 3 上操作后使用Node.replaceChild()

 const ELS_span = document.querySelectorAll(".span"); const NewEL = (tag, prop) => Object.assign(document.createElement(tag), prop); ELS_span.forEach(span => { const nodes = span.childNodes; nodes.forEach(node => { if (node.nodeType === 3) { const EL_formatting = NewEL("span", {className: "formatting", textContent: node.textContent}); span.replaceChild( EL_formatting, node ); } }); });
 .formatting { background: gold; }
 <span class="span">format me <b>bold not interested in</b> and me</span>

如果您只想获取文本,而不是子节点中的内容

 const EL_target = document.querySelector("#target"); const textOnly = [...EL_target.childNodes].reduce((a, b) => a + (b.nodeType === 3 ? b.textContent : "") , ""); console.log(textOnly); // "This is awesome!"
 <div id="target"> This is <b>pretty</b> awesome <div>indeed</div> ! </div>

文本搜索突出显示的示例

可以使用搜索输入来搜索特定单词,可以使用 new Range 来获取特定文本范围,将范围收集到一个数组中,然后用 SPAN 替换这些范围:

 const NewEL = (tag, prop) => Object.assign(document.createElement(tag), prop); const highlighter = (EL, word) => { let offset; const ranges = []; const createRange = (pos) => { const R = new Range(); R.setStart(pos.node, pos.start); R.setEnd(pos.node, pos.end); ranges.push(R); }; const rec = (node, str) => { const i = str.toLowerCase().indexOf(word.toLowerCase()); if (i < 0) return; const end = i + word.length; createRange({ node, start: offset + i, end: offset + end }); offset += end; rec(node, str.slice(end)); // Recursion! }; EL.childNodes.forEach(node => { if (node.nodeType === 3) { offset = 0; rec(node, node.textContent); } }); ranges.forEach((R) => { const SPAN = NewEL("span", { className: "formatting", textContent: R.toString() }); R.deleteContents(); R.insertNode(SPAN) }); }; let EL_target = document.querySelector("#target"); const EL_target_HTML = EL_target.innerHTML; const EL_search = document.querySelector("#search"); EL_search.addEventListener("input", () => { const val = EL_search.value; EL_target.innerHTML = EL_target_HTML; // Reset to previous HTML if (!val) return; highlighter(EL_target, val); });
 .formatting { background: gold; }
 Search text only (no children elements):<br> <input id="search" type="search" autocomplete=off> <div id="target"> Lorem ipsum <b>ignore this Lorem</b> Lorem and dolor lorem asd this lorem </div>

如果您不想丢失事件侦听器,因为上面用先前 HTML 的旧图像替换了 HTML,请使用 Range.getBoundingClientRect(); 并仅突出显示这些矩形的坐标。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM