【问题标题】:Regex replace string but not inside html tag正则表达式替换字符串但不在 html 标记内
【发布时间】:2010-11-12 14:51:27
【问题描述】:

我想用 JavaScript 替换 HTML 页面中的字符串,但忽略它,如果它在 HTML 标记中,例如:

<a href="google.com">visit google search engine</a>
you can search on google tatatata...

我想将google 替换为&lt;b&gt;google&lt;/b&gt;,但这里不是:

<a href="google.com">visit google search engine</a>
you can search on <b>google</b> tatatata...

我试过这个:

regex = new RegExp(">([^<]*)?(google)([^>]*)?<", 'i');
el.innerHTML =  el.innerHTML.replace(regex,'>$1<b>$2</b>$3<');

但问题是:我在&lt;a&gt; 标签中找到了&lt;b&gt;google&lt;/b&gt;:

<a href="google.com">visit <b>google</b> search engine</a>
you can search on <b>google</b> tatatata...

如何解决这个问题?

【问题讨论】:

    标签: javascript html regex


    【解决方案1】:

    您最好为此使用 html 解析器,而不是正则表达式。我不确定它是否可以 100% 可靠地完成。

    【讨论】:

      【解决方案2】:

      你不能这样做,你的“google”总是在某个标签中,要么全部替换,要么全部替换

      【讨论】:

        【解决方案3】:

        您可能会也可能无法使用正则表达式。这取决于您定义条件的精确程度。说你想要替换字符串,除非它在 ​​HTML 标记中是不够窄的,因为页面上的所有内容都可能在某个 HTML 标记中(如果没有其他内容,则为 BODY)。

        为此遍历 DOM 树可能会更好,而不是尝试在 HTML 上使用正则表达式。

        【讨论】:

        • 我同意。查找 DOM 中包含该字符串的所有文本节点。保留您不想要替换字符串的标签黑名单。检查文本节点是否在这些标签之一内。如果没有,请更换,否则保持原样。
        【解决方案4】:

        用正则表达式解析 HTML 并不容易,因为 HTML 不是正则。

        有关详细信息,请参阅this Stackoverflow question(和答案)。

        【讨论】:

          【解决方案5】:

          好吧,由于所有内容都是标签的一部分,因此您的请求没有任何意义。如果它只是 &lt;a /&gt; 标签,您可能只检查该部分。主要是确保在新的&lt;a&gt; 之前没有尾随&lt;/a&gt; 标签

          【讨论】:

            【解决方案6】:
            【解决方案7】:

            解决方法

            如果您不能使用 html 解析器或对您的 html 结构非常有信心,请尝试以下操作:

            1. 做“坏”的改变
            2. 重复将 (]*)(]+>) 替换为 $1 几次(根据需要重复)

            这是一个简单的解决方法,但对我有用。

            缺点? 好吧...您必须为案例进行两次替换... ...>因为它仅从页面上的每个标签中删除第一个不需要的标签

            [编辑:] 解决方案

            为什么不使用 jQuery,把 html 代码放到页面中,然后做这样的事情:

            $(containerOrSth).find('a').each(function(){
             if($(this).children().length==0){
             $(this).text($(this).text().replace('google','evil')); 
             }else{
             //here You have to care about children tags, but You have to know where to expect them - before or after text. comment for more help
             }
            });
            

            【讨论】:

            • 另一个缺点是它不是解析器。
            • 嘿,我说“如果你不能使用解析器” - 所以是的,不是
            【解决方案8】:

            您可以使用 REGEX 来做到这一点,但是像 STYLE、SCRIPT 和 CDATA 这样的过滤块需要更多的工作,并且没有在以下解决方案中实现。

            大多数答案都表明“您的数据始终位于某些标签中”,但他们没有抓住重点,数据始终位于某些标签“之间”,并且您想过滤它在“标签中”的位置。

            请注意,内联脚本中的标记字符可能会破坏这一点,因此如果它们存在,则应使用此方法单独处理它们。看看这里:
            complex html string.replace function

            【讨论】:

              【解决方案9】:

              我正在使用 regex = new RegExp("(?=[^&gt;]*&lt;)google", 'i');

              【讨论】:

              • 这个前瞻适用于我的情况。请注意,仅当一个开始标记跟随关键字“google”时,替换才有效(对于有效的 HTML,应始终如此)。我还添加了“g”标志,以便正确替换同一标签内多次出现的“google”。
              猜你喜欢
              • 1970-01-01
              • 2011-05-05
              • 2012-04-04
              • 1970-01-01
              • 1970-01-01
              • 2011-03-02
              • 1970-01-01
              • 1970-01-01
              • 2018-07-13
              相关资源
              最近更新 更多