使用正则表达式在html中突出显示单词JavaScript - 几乎在那里 [英] highlight words in html using regex & javascript - almost there

查看:196
本文介绍了使用正则表达式在html中突出显示单词JavaScript - 几乎在那里的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在写一个jQuery插件,它将执行浏览器式的页面查找搜索。我需要改进搜索,但不想进入解析HTML。

目前我的方法是获取整个DOM元素和所有嵌套元素,然后只需运行给定术语的正则表达式查找/替换。在替换中,我会简单地在匹配的术语周围包围一段跨度,并将该跨度用作我的锚点以进行突出显示,滚动等。任何html标记内的任何字符都不匹配至关重要



这与我所得到的一样接近:

 (?< (^ =>)([^<]。*?)(?=< | $)

在html标签中捕获 not 中的所有字符的功能非常出色,但我无法确定如何插入搜索字词。

 输入:任何html元素(可能相当大,例如< body>)
搜索字词:1个或更多字符
替换Txt:< span class ='highlight'> $ 1< / span>

更新

当我使用 http://gskinner.com/RegExr/ ...

 正则表达式:(?< = ^ |>)(。*?)(SEARCH_STRING) =。*?< | $)
替换:$ 1< span class ='highlight'> $ 2< / span>

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

 变种origText = $( '#' + opt.targetElements)。数据( 'origText'); 
var regx = new RegExp((?< = ^ |>)(。*?)(+ $ this.val()+)(?=。*?<| $) ,'gi');
$( '#' + opt.targetElements)。每个(函数(){
变种文本= origText.replace(至REGx, '$ 1·;跨度类=' + opt.resultClass +' > $ 2< / span>');
$(this).html(text);
});

它打破了这个群体(?< = ^ |>) - 这是笨拙的还是在正则表达式引擎中的区别?



更新

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

解决方案

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



对于DOM方法( docs为 Node 界面):运行元素的所有子节点。如果孩子是元素节点,则递归运行。如果是文本节点,请在文本中进行搜索( node.data ),如果要突出显示/更改某些内容,请缩短节点的文本直到找到的位置,然后插入一个highligth-span与匹配的文本和另一个文本节点的其余文本。



示例代码(调整,原点这里):

 (函数iterate_node(node){
if(node.nodeType === 3){// Node。 TEXT_NODE
var text = node.data,
pos = text.search(/任何正则表达式/ g),// indexOf也适用
length = 5; //或者任何你找到的
if(pos> -1){
node.data = text.substr(0,pos); //在...之前分成一部分
var rest = document.createTextNode( text.substr(POS + LEN GTH)); //
之后的部分var highlight = document.createElement(span); //和
之间的部分highlight.className =highlight;
highlight.appendChild(document.createTextNode(text.substr(pos,length)));
node.parentNode.insertBefore(rest,node.nextSibling); //在
之后插入node.parentNode.insertBefore(highlight,node.nextSibling);
iterate_node(rest); //可能有更多的匹配
}
} else if(node.nodeType === 1){// Node.ELEMENT_NODE
for(var i = 0; i< node。 childNodes.length; i ++){
iterate_node(node.childNodes [i]); //在DOM
}
}
})(content)上运行递归; //任何dom节点

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


I am writing a jquery plugin that will do a browser-style find-on-page search. I need to improve the search, but don't want to get into parsing the html quite yet.

At the moment my approach is to take an entire DOM element and all nested elements and simply run a regex find/replace for a given term. In the replace I will simply wrap a span around the matched term and use that span as my anchor to do highlighting, scrolling, etc. It is vital that no characters inside any html tags are matched.

This is as close as I have gotten:

(?<=^|>)([^><].*?)(?=<|$)

It does a very good job of capturing all characters that are not in an html tag, but I'm having trouble figuring out how to insert my search term.

Input: Any html element (this could be quite large, eg <body>)    
Search Term: 1 or more characters    
Replace Txt: <span class='highlight'>$1</span>

UPDATE

The following regex does what I want when I'm testing with http://gskinner.com/RegExr/...

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

However I am having some trouble using it in my javascript. With the following code chrome is giving me the error "Invalid regular expression: /(?<=^|>)(.?)(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);
});

It's breaking on the group (?<=^|>) - is this something clumsy or a difference in the Regex engines?

UPDATE

The reason this regex is breaking on that group is because Javascript does not support regex lookbehinds. For reference & possible solutions: http://blog.stevenlevithan.com/archives/mimic-lookbehind-javascript.

解决方案

Just use jQuerys built-in text() method. It will return all the characters in a selected DOM element.

For the DOM approach (docs for the Node interface): Run over all child nodes of an element. If the child is an element node, run recursively. If it's a text node, search in the text (node.data) and if you want to highlight/change something, shorten the text of the node until the found position, and insert a highligth-span with the matched text and another text node for the rest of the text.

Example code (adjusted, origin is here):

(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

There's also highlight.js, which might be exactly what you want.

这篇关于使用正则表达式在html中突出显示单词JavaScript - 几乎在那里的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆