re与正则表达式
几乎所有编程语言都提供对正则表达式操作的支持,Python通过标准库中的re模块来支持正则表达式操作。
关于为什么要用 r’ ..‘ 字符串?
在 python 的字符串中,\ 是被当做转义字符的。在正则表达式中,\ 也是被当做转义字符。这就导致了一个问题:如果你要匹配 \ 字符串,那么传递给 re.compile() 的字符串必须是"\\\\"。
由于字符串的转义,所以实际传递给 re.compile() 的是"\\",然后再通过正则表达式的转义,"\\" 会匹配到字符"\"。这样虽然可以正确匹配到字符 \,但是很麻烦,而且容易漏写反斜杠而导致 Bug。那么有什么好的解决方案呢?原始字符串很好的解决了这个问题,通过在字符串前面添加一个r,表示原始字符串,不让字符串的反斜杠发生转义。那么就可以使用r"\\"来匹配字符\了。
比如:r'(.*) are (.*?) .*'
这是一个字符串,前面的 r 表示字符串为非转义的原始字符串,让编译器忽略反斜杠,也就是忽略转义字符。但是这个字符串里没有反斜杠,所以这个 r 可有可无。
re常用函数findall:findall(string[, pos[, endpos]])
可以简化理解findall(正则规则,待匹配字符串(pos默认为起始位置0,endpos默认为结束位置len(字符串))
作用:在字符串中找到正则表达式所匹配的所有子串,并返回一个列表,如果没有找到匹配的,则返回空列表。
正则表达式常用模式
. 表示匹配任意字符
* 表示匹配0个或者多个
+表示匹配1个或者多个
? 表示非贪婪方式匹配
a|b表示匹配a或者b
[^abc]表示匹配时排除a、排除b、排除c
(?=a)表示前向肯定界定符,匹配到a结束,但是返回值不含a。
在urllib里出现的这段代码,加黑行进行了修正
简单实用的完整代码示例:将某个页面所有符合条件的图片下载到本机
#coding =utf-8
import urllib
import urllib2
import re
imglist=[]
def getHtml(url):
page = urllib2.urlopen(url) ##打开页面
htmla = page.read() ##获取目标页面的源码
return htmla
def getImg(html):
html = html.decode('utf-8') ##编码方式为utf-8
imglist = re.findall(r'//www+[^ ]+png.*?(?=")',html) ##解析页面源码获取图片列表
for i in range(len(imglist)):
imgurl = imglist[i]
imgurl="http:"+imgurl
print imgurl
urllib.urlretrieve(imgurl,'%s.png'% (i+1)) ##将图片从远程下载到本地并保存
def main():
html = getHtml("http://www.baidu.com")
getImg(html)
print 'End!'
main()
解释参考下述
体会*和+匹配模式的区别
html='adf123456y1ua adf4567u adf12y1ea adf12y1a'
print re.findall(r'y1.*?a',html)
print re.findall(r'y1.+?a',html)
输出:
['y1ua', 'y1ea', 'y1a']
['y1ua', 'y1ea']
体会a、(?<=a)和(?=a)匹配模式的区别
print re.findall(r'adf+[^ ]+y1.*?a',html)
print re.findall(r'adf+[^ ]+y1.*?(?<=a)',html)
print re.findall(r'adf+[^ ]+y1.*?(?=a)',html)
输出:
['adf123456y1ua', 'adf12y1ea', 'adf12y1a']
['adf123456y1ua', 'adf12y1ea', 'adf12y1a']
['adf123456y1u', 'adf12y1e', 'adf12y1']
体会用\S表示非空字符、\b...\b匹配单词边界(注意单词是以空格或引号等间隔符划分的)
import re
list='SEE SEA SURE SEEK SNEEK STORE ANSWER'
print re.findall(r'\bS\S*?E\b',list) #匹配以S开头以E结尾的单词
print re.findall(r'\bS\S*?E\S*?\b',list) #匹配以S开头含有E的单词
print re.findall(r'\b\S*?S\S*?E\S*?\b',list) #匹配含有S和E的单词
输出:
['SEE', 'SURE', 'STORE']
['SEE', 'SEA', 'SURE', 'SEEK', 'SNEEK', 'STORE']
['SEE', 'SEA', 'SURE', 'SEEK', 'SNEEK', 'STORE', 'ANSWER']
list='SNEEKSEA SURE SEEK SNE1EK STORE ANSWERSNEEK'
print re.findall(r'^(?!.*SNEEK).*',list) #匹配不含SNEEK的字符串,不含返回整条字符串,含返回空
print re.findall(r'.*SNEEK.*',list) #匹配含SNEEK的字符串,含返回整条字符串,不含返回空
输出:
[]
['SNEEKSEA SURE SEEK SNE1EK STORE ANSWERSNEEK']
最后类比
list='src="//www.baidu.com/img/bd_logo1.png" qua=high go src="//www.baidu.com/img/bd_logo1.png?qua=high" width="270" src="//www.baidu.com/img/baidu_jgylogo3.gif" alt="123" src="//www.baidu.com/img/baidu_resultlogo@2.png"'
print re.findall(r'//www+[^ ]+png.*?"',list)
print re.findall(r'//www+[^ ]+png.*?(?=")',list)
print re.findall(r'\b(?=www.baidu.com)\S*?png.*?(?=")\b',list) #没研究出来带//的写法
输出:
['//www.baidu.com/img/bd_logo1.png"', '//www.baidu.com/img/bd_logo1.png?qua=high"', '//www.baidu.com/img/baidu_resultlogo@2.png"']
['//www.baidu.com/img/bd_logo1.png', '//www.baidu.com/img/bd_logo1.png?qua=high', '//www.baidu.com/img/baidu_resultlogo@2.png']
['www.baidu.com/img/bd_logo1.png', 'www.baidu.com/img/bd_logo1.png?qua=high', 'www.baidu.com/img/baidu_resultlogo@2.png']
学习参考:
https://www.cnblogs.com/hello-wei/p/10181055.html *****
https://blog.csdn.net/weixin_40907382/article/details/79654372 ***
https://deerchao.net/tutorials/regex/regex.htm 正则表达式干货教程 *******