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表示非空字符、...匹配单词边界(注意单词是以空格或引号等间隔符划分的)
import re
list='SEE SEA SURE SEEK SNEEK STORE ANSWER'
print  re.findall(r'SS*?E',list) #匹配以S开头以E结尾的单词
print  re.findall(r'SS*?ES*?',list) #匹配以S开头含有E的单词
print  re.findall(r'S*?SS*?ES*?',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'(?=www.baidu.com)S*?png.*?(?=")',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 正则表达式干货教程  *******
 
 
原文地址:https://www.cnblogs.com/myshuzhimei/p/11776866.html