0

我正在编写一个 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>

更新

当我使用http://gskinner.com/RegExr/进行测试时,以下正则表达式可以满足我的需求...

Regex: (?<=^|>)(.*?)(SEARCH_STRING)(?=.*?<|$)
Replacement: $1<span class='highlight'>$2</span>

但是我在我的javascript中使用它时遇到了一些麻烦。使用以下代码,chrome 给我错误“无效的正则表达式:/(?<=^|>)(. ?)(Mary)(?=. ?<|$)/: Invalid group”。

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);
});

它打破了组 (?<=^|>) - 这是笨拙的东西还是正则表达式引擎的差异?

更新

该正则表达式在该组中中断的原因是因为 Javascript 不支持正则表达式后视。供参考和可能的解决方案:http: //blog.stevenlevithan.com/archives/mimic-lookbehind-javascript

4

1 回答 1

0

只需使用 jQuerys 内置text()方法。它将返回选定 DOM 元素中的所有字符。

对于 DOM 方法(接口文档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

还有highlight.js,这可能正是您想要的。

于 2012-05-02T15:30:24.013 回答