除了 <br> 标签外,移除所有 HTML 标签的正则表达式

4

我正在尝试使用JavaScript编写正则表达式,从输入字符串中删除所有HTML标签,除了<br>

我使用/(<([^>]+)>)/ig来匹配标签,并尝试过一些添加[^(br)]的方法,但现在我有点困惑了。

有人可以帮忙吗?我相信这将成为SO大师之间的速度比赛,所以如果答案解释了表达式的逻辑,我会选择它而不是其他答案。

编辑:

对于所有“不要这样做”的人,让我引用Stack Overflow中的以下内容:

虽然说让正则表达式解析任意HTML就像请Paris Hilton编写操作系统一样不切实际,但有时解析一个有限的、已知的HTML集合是合适的。

在这种情况下,它是一个包含在许多页面中保持一致的div中的大量文本。我只想摆脱一些情况(最多1%),其中用户已经包含了spans,strongs和其他一些格式标签。它不值得更多的时间来正则表达式处理,因为在我处理的成千上万个页面中几乎不会发生。如果您有更好、更快实现的想法,请随意发布它作为答案;)
编辑2
如此多的评论,我感觉需要添加一个声明: 使用正则表达式解析HTML是不好的。它无法保持一致,并且有更好的方法。Domparser已经被提到;在Node.js上有Cheerio或jsdom,还有很多库可以正确解析HTML文档(在99%的情况下)。在这种情况下,它更像是一个包含需要删除的一些<...>的字符串。

1
提示:使用正则表达式解析HTML内容从来都不是一个好主意。 - emerson.marini
1
强制性的禁止操作链接:https://dev59.com/X3I-5IYBdhLWcg3wq6do - Paul S.
1
https://dev59.com/X3I-5IYBdhLWcg3wq6do#1732454 - j08691
这是一个庞大的正则表达式,它漂浮在网络世界中,成为人们噩梦的一部分。 - user557597
1
text = text.replace(/<(?!br\s*\/?>)[^<>]*>/ig, ''); 这段代码可以很好地完成任务。 - ridgerunner
显示剩余5条评论
4个回答

7

试试这个:

/(<((?!br)[^>]+)>)/ig

只是一个有趣的点。这个正则表达式将不会匹配任何以“/br/i”开头的标签名。 - user557597

2
使用DOMParser来解析字符串,然后遍历它(我使用了这个问题中的代码),提取您感兴趣的部分:

var str = "<div>some text <span>some more</span><br /><a href='#'>a link</a>";
var parser = new DOMParser();
var dom = parser.parseFromString(str, "text/html");
var text = "";
var walkDOM = function (node, func) {
    func(node);
    node = node.firstChild;
    while (node) {
        walkDOM(node,func);
        node = node.nextSibling;
    }
};

walkDOM(dom, function (node) {
    if (node.tagName === 'BR') {
        text += node.outerHTML;
    }
    else if (node.nodeType === 3) { // Text node
        text += node.nodeValue;
    }        
});

alert(text);


是的,那就是我想要避免的。我的问题真的没有必要包含它 ;) 谢谢,不过这是一个很棒的代码片段,将来会很有用的。 - xShirase
没问题,如果您觉得有用的话,可以随意点赞。个人建议使用这种方法,因为从整体上看,它并不需要太多行代码,而且比正则表达式更加灵活。值得养成摆脱使用正则表达式解决此类问题的习惯,并获得更多以结构化方式遍历HTML的经验。 - Tom Fenech
我以编写网络爬虫为生,因此我经常使用正则解析器,并且我完全同意您的原则。在这种情况下,只是不值得,一个我只用过一次的小脚本,在这里争论的时间比我编码的时间还要长,已经完成了工作。一切都结束了。大局并没有受到干扰,自然秩序得到了恢复。各位,认真点,不要使用正则表达式来解析HTML,这是不好的。 - xShirase
说得不错,我猜这种问题的问题在于除了你之外没有人知道你要处理的字符串范围的确切格式,所以不可能知道基于正则表达式的解决方案将在哪里失败。另一方面,基于解析器的方法很可能会成功。 - Tom Fenech

0

最终我使用了:

.replace('<br>','%br%').replace(/(<([^>]+)>)/g,'')

然后我在'%br%'上进行了分割,而不是常规的br标签。 它不是HTML解析器,我确信它无法解析全球网络的100%,但它可以100%解决我的特定问题(已经尝试并测试过)。


你不需要 i 修饰符。 - user557597
它会删除这个<tag att1 = ">hello world" att2 = 'ab"c'/>吗? - user557597
@sln 不会的,但我的数据集只包含了一些<strong>、几个<span>、<i>和另外几个。 - xShirase

0

这可能会起作用。但是,无论正则表达式如何,它都无法解析HTML。

 # /(?!<\/?br\s*\/?>)<[^>]+>/g

 (?! < /? br \s* /? > )
 < [^>]+ >

在这种情况下,使用常规的HTML解析器会过于复杂,实际上只需要处理几个标签即可。 - xShirase

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接