【问题标题】:js regex: replace words not in a span tagjs正则表达式:替换不在span标签中的单词
【发布时间】:2015-10-12 11:41:01
【问题描述】:

例如:

var htmlString = "It's a <span title='mark'>nice day</span> and also a <span title=''>sunny day</span>, it's day for surfing.";

想将最后两个单词“day”替换为“night”,并跳过第一个带有标签跨度标题“mark”的单词。

var replaceString = "day";
var reg=new RegExp("(?!title=\'mark\'>).*"+replaceString+".*(?!<\/span>)","gi")    
var bb=htmlString.replace(reg,"night");    
alert(bb) 

// I can not get the right result with the above code
// Final result wanted: "It's a <span title='mark'>nice day</span> and also a <span title=''>sunny night</span>, it's night for surfing.";

更新:以下工作,但只匹配一个句子中的3个“天”,如何使它匹配不确定的“天”数?

alert(htmlString.replace(/(<span.*?'(?!mark)'>.*?)day(.*?<\/span>)|(?!>)day/gi, "$1night$2"));

谢谢。

【问题讨论】:

  • 当您拥有 DOM 解析器触手可及时,尝试在 JavaScript 中使用正则表达式解析 HTML 会受到额外的惩罚。
  • 每周至少一次,有人想将正则表达式与 HTML 或 XML 一起使用... 看在上帝的份上,不要这样做!
  • 其实RegEx match open tags except XHTML self-contained tags中并没有提示如何在JS中解析(X)HTML。
  • @NiettheDarkAbsol 您提供给 OP 以提高他的知识的链接在哪里?
  • 代码中有一个错字(relaceString 没有'p')。

标签: javascript html regex


【解决方案1】:

您可以通过以下方式使用基于 DOM 的方法实现这一目标:

function textNodesUnder(el){
  var n, walk=document.createTreeWalker(el,NodeFilter.SHOW_TEXT,null,false);
  while(n=walk.nextNode())
  {
       if (n.parentNode.nodeName.toLowerCase() !== 'span' ||
          (n.parentNode.nodeName.toLowerCase() === 'span' &&
           n.parentNode.getAttribute("title") !== 'mark'))
      		n.nodeValue =  n.nodeValue.replace(/\bday\b/g, "night"); 
  }
  return el.firstChild.innerHTML;
} 

function replaceTextNotInSpecificTag(s) {
  var doc = document.createDocumentFragment();
  var wrapper = document.createElement('myelt');
  wrapper.innerHTML = s;
  doc.appendChild( wrapper );
  return textNodesUnder(doc);
}

var s = "It's a <span title='mark'>nice day</span> and also a <span title=''>sunny day</span>, it's day for <span>surfing day</span>.";
console.log(replaceTextNotInSpecificTag(s));

结果:

It's a &lt;span title="mark"&gt;nice day&lt;/span&gt; and also a &lt;span title=""&gt;sunny night&lt;/span&gt;, it's night for &lt;span&gt;surfing night&lt;/span&gt;.

首先,我们创建一个文档片段,然后创建一个元素 myelt,然后将其作为子元素附加到文档片段中,从而允许我们使用 dom 解析器访问 DOM 节点。

然后,使用document.createTreeWalkerSHOW_TEXT 过滤器,我们可以访问所有文本节点。我们遍历节点,如果节点名不是span或者是一个title属性值不等于“mark”的span标签,我们进行查找替换。

【讨论】:

  • 效果很好!我根据需要使用了一个变量:replace(keyword, "&lt;span id='red' title='mark'&gt;"+newKeyword+"&lt;/span&gt;");,还有两件事需要改进。 1. 我没有使用像"/"+keyword+"/gi" 这样的变量。 2.标签&amp;lt;&amp;gt;变成&amp;lt;&amp;gt;虽然浏览器可以读出但是当alert(s)看起来有点难看。谢谢。
  • 要构建动态正则表达式,您需要一个 RegExp 构造函数,RegExp(keyword, "gi")。您现在似乎也在向文本元素添加标签,但您不能。相反,您需要创建元素节点,并使用关键字设置 nodeValue。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-10
  • 1970-01-01
  • 2022-12-10
  • 2010-10-12
  • 2020-06-03
  • 2012-04-27
相关资源
最近更新 更多