我正在编写一个jquery插件,它将执行浏览器样式的页面查找。我需要改善搜索,但现在还不想解析html。
目前,我的方法是获取整个DOM元素和所有嵌套的元素,并为给定术语简单地运行正则表达式查找/替换。在替换中,我将简单地在匹配词条周围包裹一个跨度,并以该跨度为锚点来进行突出显示,滚动等操作。 至关重要的是,任何html标签内的字符都不得匹配。
这与我所获得的接近:
(?<=^|>)([^><].*?)(?=<|$)
捕获所有 不在 html标记中的字符都做得很好,但是我在弄清楚如何插入搜索词时遇到了麻烦。
Input: Any html element (this could be quite large, eg <body>) Search Term: 1 or more characters Replace Txt: <span class='highlight'>$1</span>
更新
当我使用进行测试时,以下正则表达式可以实现我想要的…
Regex: (?<=^|>)(.*?)(SEARCH_STRING)(?=.*?<|$) Replacement: $1<span class='highlight'>$2</span>
但是我在JavaScript中使用它时遇到了一些麻烦。使用以下代码,chrome给了我错误“无效的正则表达式:/(?<= ^ |>)(。 ?)(Mary)(?=。 ?<| $)/:无效的组”。
var origText = $('#'+opt.targetElements).data('origText'); var regx = new RegExp("(?<=^|>)(.*?)(" + $this.val() + ")(?=.*?<|$)", 'gi'); $('#'+opt.targetElements).each(function() { var text = origText.replace(regx, '$1<span class="' + opt.resultClass + '">$2</span>'); $(this).html(text); });
在组(?<= ^ |>)上很麻烦-这是笨拙的还是Regex引擎中的差异?
此正则表达式在该组上中断的原因是因为Javascript不支持正则表达式后向。有关参考和可能的解决方案
只需使用jQuerys内置text()方法。它将返回所选DOM元素中的所有字符。
text()
对于DOM方法针对Node接口的文档:在元素的所有子节点上运行。如果子节点是元素节点,则以递归方式运行。如果是文本节点,请搜索文本(node.data),如果要突出显示/更改某些内容,请将该节点的文本缩短到找到的位置,然后插入带有匹配文本的highligth- span,其余部分插入另一个文本节点的文字。
Node
node.data
(function iterate_node(node) { if (node.nodeType === 3) { // Node.TEXT_NODE var text = node.data, pos = text.search(/any regular expression/g), //indexOf also applicable length = 5; // or whatever you found if (pos > -1) { node.data = text.substr(0, pos); // split into a part before... var rest = document.createTextNode(text.substr(pos+length)); // a part after var highlight = document.createElement("span"); // and a part between highlight.className = "highlight"; highlight.appendChild(document.createTextNode(text.substr(pos, length))); node.parentNode.insertBefore(rest, node.nextSibling); // insert after node.parentNode.insertBefore(highlight, node.nextSibling); iterate_node(rest); // maybe there are more matches } } else if (node.nodeType === 1) { // Node.ELEMENT_NODE for (var i = 0; i < node.childNodes.length; i++) { iterate_node(node.childNodes[i]); // run recursive on DOM } } })(content); // any dom node