使用正则表达式来搜索文本是高效快捷的方式
比如要搜索下文中的红色字体,
<tr><td>123</td><td>test</td><td width=130>keyword is ok</td></tr>
首先,我写了一个这样的正则表达式:
reg = re.compile("<td[/s|/S]*keyword[/s|/S]*?</td>", re.I)
ret = reg.search("<tr><td>test</td><td>keyword is ok</td></tr>")
/s表示匹配空格,/S表示匹配非空格,将这两种情况加在一起:[/s|/S]就表示匹配任意字符,包括字母、数字、换行符、空格等等;*表示之前的[/s|/S]可以出现0次或多次,*?则表示懒惰匹配,也就是配备离keyword最近的一个</td>,使用这个表达式匹配的最后结果是:
<td>123</td><td>test</td><td width=130>keyword is ok</td>
也就是只去掉了<tr>和</tr>,而关键字“keyword”之前的<td>显然是过渡匹配了,
现在需要改进之前的那个正则表达式,需要否定keyword的之前出现的</td>,这样就可以保证获得的字符串中不含</td>.
这时候就需要用否定环视来解决了。否定环视的具体用法是:
表达式 | 说明 |
(?<=Expression) | 逆序肯定环视,表示所在位置左侧能够匹配Expression |
(?<!Expression) | 逆序否定环视,表示所在位置左侧不能匹配Expression |
(?=Expression) | 顺序肯定环视,表示所在位置右侧能够匹配Expression |
(?!Expression) | 顺序否定环视,表示所在位置右侧不能匹配Expression |
更详细的使用方法可以参考:http://blog.youkuaiyun.com/lxcnn/archive/2009/06/28/4304754.aspx
在这里,我将正则表达式改为
reg = re.compile("<td(?:(?<!</td>).)*?keyword[/s|/S]*?</td>", re.I)
(?:(?<!</td>).)*?表示在这个正则表达式的左侧,不能出现</td>