本文介绍在Java和JavaScript中使用正则表达式处理HTML标签的方法。重点讲解如何过滤简单标签,并针对嵌套标签提供有限级匹配策略。由于Java正则引擎对高级特性支持有限,通过递归构造正则模式实现多级嵌套匹配,同时提供保留特定标签(如img)的替换技巧及常见正则用例。
JavaScript过滤HTML标签基础
在JavaScript中,利用正则表达式替换HTML标签及空格( )是常见的文本处理需求。
相关的JavaScript实现代码如下:
function filter(text) {
var reg = /<[^<>]+>/g;//1、全局匹配g肯定忘记写,2、<>标签中不能包含标签实现过滤HTML标签
text = text.replace(reg, '');//替换HTML标签
text = text.replace(/ /ig, '');//替换HTML空格
return text;
};
在AngularJS框架中,可以通过自定义过滤器来处理富文本数据,实现标签过滤。
app.filter('qxhtml', function () {
return function (text) {
var reg = /<[^<>]+>/g;
text = text.replace(reg, '');
text = text.replace(/ /ig, '');
if (text.length > 50) {
text = text.substring(0, 50) + "...";
}
return text;
};
});
具体使用过滤器的方式如下:
<div class="desc"> {{y.Description| qxhtml}} </div>
以下是其他网友提供的补充方案。
JavaScript如何使用正则表达式过滤HTML标签?核心正则模式为 /<[^<>]+>/g。
一、总结(点击显示或隐藏总结内容)
JavaScript进阶:利用正则表达式过滤HTML标签,关键在于确保<>标签内部不包含其他标签,正则模式为 /<[^<>]+>/g。
var reg=/<[^<>]+>/g
1、全局匹配标志g不可省略。 2、<>标签中不能包含其他标签,以此实现HTML标签的过滤。
二、JavaScript进阶:正则表达式过滤HTML标签
实例描述:将包含HTML标签的文本中的标签去除,转换为纯文本输出。
三、代码实现
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>过滤HTML标签</title>
<style type="text/css">
textarea{
width: 60%;
font-size: 18px;
background: rgba(100,200,50,0.3);
}
#text2{
background:rgba(200,100,50,0.3);
}
</style>
</head>
<body>
<textarea id="text1" rows="10" cols="50"></textarea><br><br>
<input type="button" id="btn1" value="过滤HTML标签"><br><br>
<textarea id="text2" rows="10" cols="50"></textarea>
<script type="text/javascript">
var btn1=document.getElementById('btn1')
var text1=document.getElementById('text1')
var text2=document.getElementById('text2')
btn1.onclick=function (){
//var reg=/<.+>/g
var reg=/<[^<>]+>/g //1、全局匹配g肯定忘记写 2、<>标签中不能包含标签实现过滤HTML标签
text2.value=text1.value.replace(reg,'')
}
</script>
</body>
</html>
JavaScript正则表达式去除HTML字符中所有标签(保留img标签)的方法。
直接展示代码:
description.replace(/<(?!img).*?>/g, "");
若需同时保留img和p标签,则修改正则如下:
description.replace(/<(?!img|p|\/p).*?>/g, "");
在JavaScript字符串中,斜杠/需要使用转义字符处理。
Java与JavaScript中有限级嵌套标签匹配
通用HTML标签匹配正则表达式。
近期查看网站日志时,发现有人转载了多年前编写的一个匹配HTML标签的正则表达式。鉴于最近也在处理相关任务,便对此进行了改进,形成了下述版本。该正则可能存在部分边界情况遗漏,欢迎修正。已知其在处理内嵌<script>复杂内容时能力较弱,但对于纯HTML结构的分析工具而言已足够使用。
<script type="text/javascript">
var str = "<br /><br/><br><br ><中文><div><div id=a>无忧脚本<img src=\"http://bbs.51js.com/images/default/logo.gif\" width=\"191\" height='75' border=0 onload=\"if(testver>0 && testver<500)alert('test');\" \n onerror='alert(\"test\")' /><img src=xxx alt=\"hello\njust a test!\"></div><hr ><script type=\"test/javascript\" defer>alert(\"just a test!\");<\/script>Hello.<input type=text value=\"无忧脚本\"><br / ><img \"\" ></ ><!-- 注释 -->< ucren><!-- 再<注>释 --><img alt=' title='\"' /><b>123</b>1<2<3,3<4>1<b><img src=\"http://bbs.51js.com/images/old51js/logo.gif\" /><!-- 三注释>>> -->";
var reg = /<(?:(?:\/?[A-Za-z]\w*\b(?:[=\s](['"]?)[\s\S]*?\1)*)|(?:!--[\s\S]*?--))\/?>/g;
alert(str.match(reg).join("\n----------------------------------------------------\n"));
</script>
在线测试链接
[Ctrl+A 全选 注:引入外部Js需再刷新一下页面才能执行]
有用户反馈Java环境下直接使用该正则会报错。经查阅,Java正则引擎支持的特性相对较少。在1.6版本中无法使用命名组(据称1.7版本开始支持),否则将抛出如下异常,更不用说平衡组等高级特性。因此,实现无限级嵌套匹配在Java中显得不切实际。
java.util.regex.PatternSyntaxException: Look-behind group does not have an obvious maximum length near index XX
尽管网络上未找到完美的通用解决方案,但我们可以实现有限级HTML嵌套标签的匹配。相较于无限级匹配,思路更为简单,无需依赖过多高级特性。 示例如下:
<div id='container'><BR> <div style='background-color:gray;' id='footer'><BR> <a id='gotop' href='#' onclick='MGJS.goTop();return false;'>Top</a><BR> <a id='powered' href='http://wordpress.org/'>WordPress</a><BR> <div id='copyright'><BR> Copyright © 2009 简单生活 —— Kevin Yang的博客<BR> </div><BR> <div id='themeinfo'><BR> Theme by <a href='http://www.neoease.com/'>mg12</a>. Valid <a href='http://validator.w3.org/check?uri=referer'>XHTML 1.1</a><BR> and <a href='http://jigsaw.w3.org/css-validator/'>CSS 3</a>.<BR> </div><BR> </div><BR></div>
在上述示例中,目标是匹配id为footer的嵌套div,且假设预先已知该div内部最多仅嵌套一级div。对于更多层级的情况,后续将展开讨论。 footer的起始和结束标签匹配相对简单:
<div [^>]*id='footer'[^>]*>......(这里的省略号是一会要填写的)</div>
夹在起始和结束标签之间的内容主要包含两种情况: 内容A: div标签,且此div内部无嵌套div 内容B: 任意其他内容 接下来即是对这两种内容的重复匹配。正则表达式如下:
(<div[^>]*>.*?</div>|.)*?
需注意末尾的问号必须保留,否则受正则贪婪匹配特性影响,footer的闭合标签可能导致匹配错误。 因此,匹配最多嵌套一级div的正则表达式为:
<div [^>]*id='footer'[^>]*>(<div[^>]*>.*?</div>|.)*?</div>
若footer标签内部最多嵌套两级div,该如何处理? 方法并不复杂,只需对前述“内容A”部分中的点号进行适当替换即可。修改后的正则如下:
<div [^>]*id='footer'[^>]*>(<div[^>]*>(<div[^>]*>.*?</div>|.)*?</div>|.)*?</div>
至此,推测匹配最多嵌套三级div的正则表达式写法应为:
<div [^>]*id='footer'[^>]*>(<div[^>]*>(<div[^>]*>(<div[^>]*>.*?</div>|.)*?</div>|.)*?</div>|.)*?</div>
由此可见,只要HTML结构并非极度复杂,即嵌套层级不深,完全可采用这种方式来匹配嵌套HTML标签。
该正则表达式在Java和JavaScript中均可通用,因其未使用任何高级特性。
常见HTML元素正则匹配示例
接着补充其他常见用例。
查找所有TD区域(最短匹配):
<td\s*.*>\s*.*<\/td>
查找所有TR:
<tr.*(?=>)(.|\n)*?</tr>
查找所有TD:
<td.*(?=>)(.|\n)*?</td>
正则表达式匹配HTML标签示例。
例1. 以下是一段Html代码
<table boder="0" width="11%" class="somestory">
<tr>
<td width="100%">
<p align="center">其它内容...</p>
</td>
</tr>
</table>
<table border="0" width="11%" class="headline">
<tr>
<td width="100%">
<p align="center">典经HTML正则表达式!</p>
</td>
</tr>
</table>
<table boder="0" width="11%" class="someotherstory">
<tr>
<td width="100%">
<p align="center">其它内容...</p>
</td>
</tr>
</table>
正则表过式:<table.*(?=headline)
说明:正则表达式匹配表格开始标记,能够返回开始标记直至 “headline”之间的所有内容(换行除外);
即以上红色标示出来的部分。
原理:
<table //匹配的开始部分
.* //除换行外的所有字符
(?=headline) //零宽度正预测先行断言,匹配以 headline 结尾的单词的前面部分(除了 headline 以外的部分)
例2.
<table boder="0" width="11%" class="somestory">
<tr>
<td width="100%">
<p align="center">其它内容...</p>
</td>
</tr>
</table>
<table border="0" width="11%" class="headline">
<tr>
<td width="100%">
<p align="center">典经HTML正则表达式!</p>
</td>
</tr>
</table>
<table boder="0" width="11%" class="someotherstory">
<tr>
<td width="100%">
<p align="center">其它内容...</p>
</td>
</tr>
</table>
正则表达式:<table.*(?=headline)(.|\n)*?</table> 说明:匹配最长的以 <table border="0" width="11%" class=" 开始, 以</table>结束的字符串,即以上以红色标示出来的部分。
原理:
<table.*(?=headline) //参见记录1的说明 (.|\n) //指示在两个或多个项之间进行选择,(zlf)ood 与 "zood" 或 "food" 匹配 *? //应与上一个 (.|\n) 联合起来看, .*? 就意味着匹配任意数量的重复,但是在能使整个匹配成功的前提下使用最少的重复,懒惰模式。 </table> //匹配的结束标记
注意:“(.|\n)”后面的 "*" 匹配 0 个到多个任意字符,而“?”使得“*”匹配范围最小化,即在找到表达式的下一部分之前匹配尽可能少的字符。</table> 是表格的结束标记.
例3.
<tableboder="0" width="11%" class="somestory">
<tr>
<td width="100%">
<p align="center">其它内容...</p>
</td>
</tr>
</table>
<tableborder="0" width="11%" class="headline">
<tr>
<td width="100%">
<p align="center">典经HTML正则表达式!</p>
</td>
</tr>
</table>
<tableboder="0" width="11%" class="someotherstory">
<tr>
<td width="100%">
<p align="center">其它内容...</p>
</td>
</tr>
</table>
正则表达式:<(?<tag>[^\s>]+)[^>]*>(.|\n)*?</\k<tag>> 说明:匹配成对的HTML标签,它将匹配Html标签及标签中的内容,本例分三段匹配三个<table>标签及</table>中的内容。 原理: < //html标签中的 < (?<tag>[^\s>]+) // (?<name>), 分组命名的方式,[^\s>]:非任何空白字符及“>”至少匹配一次 [^>]*> //非“>”匹配 0 到 n 次,及html的标签“>”. (.|\n) //在两个或多个项之间时行选择,(zlf)ood 与 "zood" 或 "food" 匹配. *? // 应与上一个(.|\n)联合起来看, .*? 就意味着匹配任意数量的重复,但是在能使整个匹配成功的前提下使用最少的重复,懒惰模式。 </\k<tag>> //反向引用命名的组,语法为 \k<name>, 及html 标签“>”
注意:“(.|\n)”后面的 "*" 匹配 0 个到多个任意字符,而“?”使得“*”匹配范围最小化,即在找到表达式的下一部分之前匹配尽可能少的字符。
本例使用了分组命名及反向引用命名组的概念。
正则表达式匹配中文的处理方法。
匹配中文字符的正则表达式: [\u4e00-\u9fa5] 1、先用js把中文转换16进制码:d.innerHTML = escape("你们"); 得到 %u4F60%u4EEC, 即 \u4F60\u4EEC 2、var arr = str.match(/\u4F60\u4EEC/g); 3、\u4F60为单个汉字“你”. 4、以上测试程序为javascript
到此这篇关于Java/Js下使用正则表达式匹配嵌套Html标签的文章就介绍到这了,更多相关正则表达式匹配嵌套Html标签 内容请搜索本站以前的文章或继续浏览下面的相关文章希望大家以后多多支持本站!