用于可见文本的正则表达式,而不是HTML

时间:2011-06-23 06:50:45

标签: javascript jquery html regex

如果我有一个字符串:

hey <a href="#user">user</a>, what are you doing?

如何使用正则表达式:在user<个字符中查找>,但?因此匹配会抓住<a></a>之间的用户,而不是href

内的用户

我希望这适用于任何标签,所以不管是什么标签。

==更新==

为什么我不能使用.text()或innerText是因为它被用来突出显示结果,就像浏览器中的原生cmd / ctrl + f功能一样,我不想丢失格式。例如,如果我在这里搜索strong

Some <strong>strong</strong> text.

如果我使用.text()它会返回“一些强文本”,然后我将strong包裹一个<span>,其中有一个样式类,但现在当我回去时尝试将其插入DOM中,它将缺少<strong>标记。

7 个答案:

答案 0 :(得分:7)

如果您计划再次使用html()替换HTML,那么您将丢失可能绑定到内部元素及其data的所有事件处理程序(正如我在评论中所述)。

每当您将元素的内容设置为HTML字符串时,您就是在创建新元素。

最好将此函数递归应用于每个文本节点。类似的东西:

$.fn.highlight = function(word) {
    var pattern = new RegExp(word, 'g'),
        repl = '<span class="high">' + word + '</span>';

    this.each(function() {
        $(this).contents().each(function() {
            if(this.nodeType === 3 && pattern.test(this.nodeValue)) {
                $(this).replaceWith(this.nodeValue.replace(pattern, repl));
            }
            else if(!$(this).hasClass('high')) {
                $(this).highlight(word);
            }
        });
    });
    return this;
};

DEMO

但很可能这不是很有效率。

答案 1 :(得分:2)

要模拟Ctrl-F(我假设您正在做的事情),您可以将window.find用于Firefox,Chrome和Safari以及TextRange.findText用于IE。

您应该使用功能检测来选择您使用的方法:

function highlightText(str) {
    if (window.find)
        window.find(str);
    else if (window.TextRange && window.TextRange.prototype.findText) {
        var bodyRange = document.body.createTextRange();
        bodyRange.findText(str);
        bodyRange.select();
    }
}

然后,在选择文本后,您可以使用::selection选择器为CSS选择样式。

编辑:要在某个DOM对象中进行搜索,您可以使用环形交叉口方法:使用window.find并查看选择是否在某个元素中。 (或许可以说s = window.getSelection().anchorNode并比较s.parentNode == objs.parentNode.parentNode == obj等。如果它不在正确的元素中,请重复此过程。 IE更容易:代替document.body.createTextRange(),您可以使用obj.createTextRange()

答案 2 :(得分:1)

$("body > *").each(function (index, element) {

  var parts = $(element).text().split("needle");
  if (parts.length > 1)
    $(element).html(parts.join('<span class="highlight">needle</span>'));
});

jsbin demo

此时它正在变得越来越像菲利克斯,所以我认为他有胜利者


原:

如果您是在javascript中执行此操作,那么已经在DOM中有一个方便的解析版本的网页。

// gives "user"
alert(document.getElementById('user').innerHTML);

或者使用jQuery,你可以做很多不错的快捷方式:

alert($('#user').html()); // same as above

$("a").each(function (index, element) {
    alert(element.innerHTML); // shows label text of every link in page
});

答案 3 :(得分:0)

试试这个:

/[(<.+>)(^<)]*user[(^>)(<.*>)]/

这意味着:

在关键字之前,您可以拥有尽可能多的<...>non-<

相同之后。

修改

正确的是:

/((<.+>)|(^<))*user((^>)|(<.*>))*/

答案 4 :(得分:0)

我喜欢正则表达式,但因为标签可以嵌套,所以你必须使用解析器。我推荐http://simplehtmldom.sourceforge.net/它非常强大且易于使用。如果你有良好的xhtml格式,你也可以使用php中的SimpleXML。

编辑:没有看到javascript标记。

答案 5 :(得分:0)

这是有效的,我在你的JS Bin上尝试过:

var s = 'hey <a href="#user">user</a>, what are you doing?';
s = s.replace(/(<[^>]*)user([^<]>)/g,'$1NEVER_WRITE_THAT_ANYWHERE_ELSE$2');
s = s.replace(/user/g,'Mr Smith');
s = s.replace(/NEVER_WRITE_THAT_ANYWHERE_ELSE/g,'user');
document.body.innerHTML = s;

这可能有点复杂,但它确实有效!

说明:

  • 您可以使用您选择的随机字符串替换标记中 的“用户”(这很容易找到),您永远不能再使用它。一个很好的用法是用它的哈希码(md5,sha-1,...)
  • 替换它
  • 用您想要的文字替换“user”的每个剩余发生。
  • 用“user”替换您的唯一字符串。

答案 6 :(得分:-1)

此代码将从sting中删除所有标记

var s = 'hey <a href="#user">user</a>, what are you doing?';
s = s.replace(/<[^<>]+>/g,'');