仅用RegExp替换字符串中的外部标签

Replace with RegExp only outside tags in the string

本文关键字:外部 标签 字符串 RegExp 替换 仅用      更新时间:2023-09-26

我有一个字符串,其中一些html标签可以显示,如

this is a nice day for bowling <b>bbbb</b>

我如何用RegExp替换所有b符号,例如,用:blablabla:(例如),但只有在html标签之外?

那么在这种情况下,结果字符串应该是

this is a nice day for :blablabla:owling <b>bbbb</b>

EDIT:我想根据我收到的答案更具体一些。首先,我只有一个字符串,不是DOM元素,也不是别的什么。字符串可以包含也可以不包含标签(开始和结束)。主要思想是能够替换文本中的任何地方,除了标签。例如,如果我有一个像

这样的字符串
not feeling well today :/ check out this link <a href="http://example.com">http://example.com</a>

regexp应该替换只有第一个:/与真正的笑脸图像,但不应该替换第二个和第三个,因为他们是内部(和一部分)标签。下面是使用其中一个答案的regexp的示例片段。

var s = 'not feeling well today :/ check out this link <a href="http://example.com">http://example.com</a>';
var replaced = s.replace(/(?:<[^'/]*?.*?<'/.*?>)|(:'/)/g, "smiley_image_here");
document.querySelector("pre").textContent = replaced;
<pre></pre>

这是奇怪的,但DEMO显示它捕获了正确的组,但在replace函数中相同的regexp似乎不起作用。

:blablabla:替换所有b s的正则表达式本身并不难:

.replace(/b/g, ":blablabla:")

获取我们需要执行搜索和替换的文本节点有点棘手。

下面是一个基于dom的例子:

function replaceTextOutsideTags(input) {
  var doc = document.createDocumentFragment();
  var wrapper = document.createElement('myelt');
  wrapper.innerHTML = input;
  doc.appendChild( wrapper );
  return textNodesUnder(doc);
}
function textNodesUnder(el){
  var n, walk=document.createTreeWalker(el,NodeFilter.SHOW_TEXT,null,false);
  while(n=walk.nextNode())
  {
       if (n.parentNode.nodeName.toLowerCase() === 'myelt')
      		n.nodeValue =  n.nodeValue.replace(/:'/(?!'/)/g, "smiley_here"); 
  }
  return el.firstChild.innerHTML;
} 
var s = 'not feeling well today :/ check out this link <a href="http://example.com">http://example.com</a>';
console.log(replaceTextOutsideTags(s));

在这里,我们只修改自定义创建的名为myelt的元素的直接子元素的文本节点。

结果:

not feeling well today smiley_here check out this link <a href="http://example.com">http://example.com</a>

var input = "this is a nice day for bowling <b>bbbb</b>";
var result = input.replace(/(^|>)([^<]*)(<|$)/g, function(_,a,b,c){
				return a
				+ b.replace(/b/g, ':blablabla:')
				+ c;
});
document.querySelector("pre").textContent = result;
<pre></pre>

你可以这样做:

var result = input.replace(/(^|>)([^<]*)(<|$)/g, function(_,a,b,c){
            return a
            + b.replace(/b/g, ':blablabla:') // you may do something else here
            + c;
});

请注意,在大多数(不是全部,而是大多数)实际复杂的用例中,操作已解析的DOM要比操作字符串方便得多。如果从HTML页面开始,可以使用库(有些库,比如我的库,接受正则表达式)。

我认为你可以使用这样一个正则表达式:(只是一个简单的数据,而不是一个嵌套的)

/<[^'/]*?b.*?<'/.*?>|(b)/ig
(Regex演示)


如果你想使用正则表达式,我可以建议你使用以下正则表达式来递归地删除所有标签,直到所有标签都被删除:

/<[^'/][^<]*>[^<]*<'/.*?>/g

则使用replace查找任何b

相关文章: