开发项目时客户要求新功能,受同事请求,帮他写个正则来取htm中特定标签中的多个属性值.
要求:
给定的html代码中要找出以下格式的代码,并取出各个属性值以供同事去处理
<p>[video width="320" height="240" url="http://www.youtube.com/embed/26EE3jG5thM"]</p>
思路:
从给定的代码来看,有固定的前缀和后缀,可以使用捕获型括号来取各个属性值.要注意属性的位置和特殊字符等
分析:
1.以<p>[video 开头,以]</p>结尾
2.各属性中间空格不确定
3.各属性的值可能是以单或双引号包含
4.url地址没有什么特殊字符
实现:
1.要匹配头 正则 <p>[video
2.要匹配 width="320" 正则 width=['"]\d+['"]
3.要匹配 height="240" 正则 height=['"](\d+)['"]
4.要匹配 url="http://www.youtube.com/embed/26EE3jG5thM" 正则 url=['"][:/\w]+)['"]
5.要匹配尾 正则 ]</p>
组装起来: <p>[video width=['"]\d+['"] height=['"]\d+['"] url=['"][:/\w]+['"]]</p>
6.要匹配空格使用\s+ <p>[video\s+width=['"]\d+['"]\s+height=['"]\d+['"]\s+url=['"][:/\w]+['"]]</p>
7.要取出各属性值,使用捕获括号 <p>[video\s+width=['"](\d+)['"]\s+height=['"](\d+)['"]\s+url=['"]([:/\w]+)['"]]</p>
经测试,匹配不成功,仔细检查,发现对头和尾的特殊元素[]少了转义
改正 <p>\[video\s+width=['"](\d+)['"]\s+height=['"](\d+)['"]\s+url=['"]([:/\w]+)['"]\]</p>
8.要考虑属性的位置不确认性,使用或条件,但要注意使用或条件时不能破坏了捕获括号的值,再要用到括号都使用非捕获型
且仔细分析,三个属性都是 \s+属性 这种形式重复的,则可优化成 (\s+(属性1|属性2|属性3))+ 的形式
<p>\[video(?:\s+(?:width=['"](\d+)['"]|height=['"](\d+)['"]|url=['"]([:/\w]+)['"]))+\]</p>
将此正则交与同事,不久后回复,有一地址不能匹配,一看是url中多了问号字符.问他url地址是否为特定的,他也不能确认,于是,为了最大范围匹配,再改url的值匹配
最终正则为
<p>\[video(?:\s+(?:width=['"](\d+)['"]|height=['"](\d+)['"]|url=['"]([^'"]+)['"]))+\]</p>
java中的正则用法
Matcher m = Pattern.compile(reg, Pattern.CASE_INSENSITIVE).matcher(url);
while (m.find()) {
System.out.println("width="+m.group(1));// may be null
System.out.println("height="+m.group(2));// may be null
System.out.println("url="+m.group(3));// may be null
}
其实该正则还是有优化的地方.仔细分析了其url来源,可以确定[video 是唯一的,则前后的<p>元素可以去除.
其元素是由软件生成,则位置,引号,空格都是统一的,则去除或条件,去除空格数量去除多条括号等