【问题标题】:javascript - replacing text not between in attributesjavascript - 替换不在属性之间的文本
【发布时间】:2016-03-12 18:24:33
【问题描述】:

我正在尝试用 Javascript 替换 HTML 字符串中的文本。 棘手的部分是,只有文本不在标签内时我才需要替换文本(这意味着它不是属性的一部分):

var html_str = '<div>hi blah blah<img src="img.jpg" alt="say hi" /><a href="link_hi.php">hi!</a></div>';

在此示例中,在我执行 html_str.replace("hi","hello"); 之后,我只想替换 diva 标记内的文本,避免使用 &lt;img alt=".."href="...

更多信息:

  1. html_str = document.body.innerHTML;,因此元素未知。上面的例子只是一个例子。
  2. 非常欢迎正则表达式。
  3. hihello 值在变量内部,这意味着实际替换是这样的:html_str.replace(var1,var2);

真正的代码是这样的:

var html_str = document.body.innerHTML;
var replaced_txt = "hi";
var replace_with = "hello";
var replaced_html = html_str.replace(replaced_txt,replace_with);

我希望我能很好地解释自己。 提前致谢。

【问题讨论】:

    标签: javascript regex google-chrome-extension


    【解决方案1】:

    这可能吗?

    var obj = {'hi':'hello','o':'*','e':'3','ht':'HT','javascrpit':'js','ask':'ASK','welcome':'what\'s up'}; // This may contain a lot more data
    
    (function helper(parent, replacements) {
      [].slice.call(parent.childNodes, 0).forEach(function (child) {
        if (child.nodeType == Node.TEXT_NODE) {
          for (var from in replacements) {
            child.nodeValue = child.nodeValue.replace(from, replacements[from]);
          }
        }
        else {
          helper(child, replacements);
        }
      });
    }(document.body, obj));
    

    http://jsfiddle.net/G8fYq/4/直接使用 document.body

    如果您想让更改立即可见,那么您也可以传递 document.body 并忘记整个 container 内容。

    更新以允许一次运行多个替换。


    您也可以在 javascript 中尝试 XPath,但以下解决方案在 IE 中不起作用。

    var
      replacements = {'hi':'hello','o':'*','e':'3','ht':'HT','javascrpit':'js','ask':'ASK','welcome':'what\'s up'},
      elements = document.evaluate('//text()', document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null),
      i = 0,
      textNode, from;
    
    for (; i < elements.snapshotLength; i += 1) {
      textNode = elements.snapshotItem(i);
    
      for (from in replacements) {
        if (replacements.hasOwnProperty(from)) {
          textNode.nodeValue = textNode.nodeValue.replace(from, replacements[from]);
        }
      }
    }
    

    【讨论】:

    • @Phoenix 出于好奇,为什么不呢?
    • 它只是没有用。实际上我希望这个解决方案能够奏效,它更适合我的代码。我需要在不对标签造成任何“损坏”的情况下更改 HTML 文本,而这经常发生在正则表达式中。
    • @Phoenix 那么为什么不说它是如何不工作的呢?这就是通常在这里完成的方式;)
    • 很抱歉。我尝试了所有的回答,只是检查了几乎“在盒子上”工作的那个。我认为您的解决方案的问题是需要完成的循环数量。 replace_txtreplace_with 来自可能包含大量数据的 JSON。看这个例子:jsfiddle.net/G8fYq/5
    • @Phoenix 啊,我明白你的问题了。当然,每次替换都遍历整个文档树会浪费很多 CPU 资源。我建议只遍历一次,但在每个找到的文本节点上替换多次。我相应地更新了代码,看看。 ;)
    【解决方案2】:

    实际上可以使用这个简单的正则表达式否定前瞻:

    (?![^<>]*>)
    

    只需将其添加到您的匹配模式中,它就会排除任何内容作为标签中的属性。这是一个例子: Javascript regex: Find all URLs outside <a> tags - Nested Tags

    【讨论】:

      【解决方案3】:

      你可以试试这个,但是正则表达式和 HTML 不是朋友:

      var str = '<div>hi blah blah<img src="img.jpg" alt="say hi" /><a href="link_hi.php">hi!</a></div>',
          rx = new RegExp('(\>[^\>]*)' + 'hi' + '([^\>=]*\<)', 'g');
      
      str = str.replace(rx, '$1hello$2');
      

      【讨论】:

      • 谢谢。我需要删除 ` before the >` 但对我来说效果很好。
      猜你喜欢
      • 2013-12-05
      • 2011-08-19
      • 1970-01-01
      • 2015-05-08
      • 1970-01-01
      • 2021-07-21
      • 2014-09-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多