Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/76.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 正则表达式:仅在标记中匹配文本节点_Javascript_Jquery_Html_Regex_Dom - Fatal编程技术网

Javascript 正则表达式:仅在标记中匹配文本节点

Javascript 正则表达式:仅在标记中匹配文本节点,javascript,jquery,html,regex,dom,Javascript,Jquery,Html,Regex,Dom,我一直在写一个精彩的剧本。第一个结果可以在这里找到 剧本 但不幸的是,它只适用于一个简单的字符串。我希望它能够处理包含标签的字符串 例如: <li>sample string li span style="color:red" id <span id="toto" style="color:red">color id</span> abcde </li> 示例字符串li span style=“color:red”id 颜色i

我一直在写一个精彩的剧本。第一个结果可以在这里找到

剧本

但不幸的是,它只适用于一个简单的字符串。我希望它能够处理包含标签的字符串

例如:

<li>sample string li span style="color:red" id 
    <span id="toto" style="color:red">color id</span> 
    abcde
</li>
示例字符串li span style=“color:red”id 颜色id abcde 因此,如果用户搜索
span
,它应该只匹配
  • 内部和标记
    span
    之前的span,而不匹配标记
    span
    本身。然后将匹配的字符串替换为
    span
    ,对于其他属性或属性的内容也是如此。应该忽略开始标记和结束标记内的任何内容

    因为HTML是关于DOM和节点的。我们可以将这个字符串解析为节点,然后只选择文本节点来替换它吗

    请通过更新上面的JSFIDLE来回答

    已更新


    Tibos的工作解决方案演示:

    免责声明:您应该在此处使用HTML解析器而不是regexp

    您要查找的正则表达式如下所示:

    /span(?=[^>]*<)/
    
    演示:

    编辑:添加了regexp转义:
    .replace(/[-\/\\^$*+.()\\[\]{}]/g,'\\$&')

    简而言之:

    不要试图用正则表达式获取正确的字符串,只使用textNodes:

    $('#submit').click(function () {
        var replacePattern = new RegExp(
            $('#search').val().replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'), 
            'gi');
        $('#sample').children().addBack().not('.highlight')
          .contents().filter(function() {
            return this.nodeType === 3;
        }).replaceWith(function(){
            return this.data.replace(replacePattern, '<b class="highlight">$&</b>');
        });
    });
    
    $('#提交')。单击(函数(){
    var replacePattern=newregexp(
    $('search').val(),
    ‘gi’;
    $(“#示例”).children().addBack().not(“.highlight”)
    .contents().filter(函数()){
    返回this.nodeType==3;
    }).replaceWith(函数(){
    返回此.data.replace(replacePattern,$&');
    });
    });
    

    说明:首先收集
    #sample
    元素及其子元素(仅当使用
    children()
    时才直接收集;当然也可以使用
    find(*)
    )。然后,
    .highlight
    元素从该选择中筛选出来-这显然是可选的,但对于我来说,在已经高亮显示的内容中高亮显示没有什么意义

    拥有所有元素(待处理)后,使用-收集其所有子元素,并过滤该集合(使用nodeType检查),以便只保留文本节点。最后,您浏览了该集合


    请注意,模式定义位于
    replaceWith
    回调函数的外部(因为它在单次单击处理期间基本上应该是一个常量)。

    我已经测试了您的程序。但它只匹配
    span
    之外的任何内容。示例
    toto
    不匹配。虽然部分工作,但它不是我所期望的更新了答案,添加了“儿童”选择器。工作!你是个天才。尽管我不明白你在写什么:PI添加了递归搜索的.find('*'),我添加了一个解释。)当然,可以调整此样本;这里的关键点是如何在这种情况下使用内部HTML解析器(在我看来,应该这样做)。它不起作用,如果您实际使用regexp类的全局修饰符,请使用span中的颜色、id和样式对其进行测试。完成了
    在搜索区域内不是有效字符。确实如此。我通过在搜索字符串中的所有字母之间插入
    (?:)?
    (可能是任何标记)解决了这个问题。我没有让它与逃跑部分的工作,这是你做的。这开始让人感觉不到“我需要一些帮助”,而更像是“这是规范,做吧!”所以我不再试图解决您可能遇到的任何问题。一切都很好。我只是指出,SO被认为更像是在正确的方向上推动,而不是给出一个有效的解决方案,而你自己在试图解决其他问题上付出的努力似乎不够。无论如何,我很高兴能帮上忙。
    /span(?=[^>]*(?:<|$))/
    
    $('#submit').click(function () {
        var replacePattern = new RegExp(
            $('#search').val().replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'), 
            'gi');
        $('#sample').children().addBack().not('.highlight')
          .contents().filter(function() {
            return this.nodeType === 3;
        }).replaceWith(function(){
            return this.data.replace(replacePattern, '<b class="highlight">$&</b>');
        });
    });