1.通配符
通配符是一种特殊语句,主要有星号(*)和问号(?),用来模糊搜索文件。当查找文件夹时,可以使用它来代替一个或多个真正字符;当不知道真正字符或者懒得输入完整名字时,常常使用通配符代替一个或多个真正的字符。 实际上用“*Not?pad”可以对应Notpad\MyNotpad【*可以代表任何文字】;Notpad\Notepad【?仅代表单个字】;Notepad\Notepod【ao代表a与o里二选一】,其余以此类推。
通配符是竞价排名广告的一项高级功能,当我们在广告创意中使用了这项功能之后,使用不同搜索字词的用户将看到不同的广告创意(虽然我们只制作了一个广告)。这将大大提高我们广告的相关性和实用性,从而提高广告的点击率,同时也大大提高了我们的工作效率。
2.正则表达式
import re
s = "kiosk/home/kiosk/westosanaconda2/envs/blog/bin/python3.6/home/kiosk/Desktop/day25"
# s.find('westos')
# ***************************findall方法********************************
# 1. 编写正则的规则
pattern1 = r'westos'
pattern2 = r'kiosk'
# 2. 通过正则去查找匹配的内容
print(re.findall(pattern1, s))
print(re.findall(pattern2, s))
# ************************match********************************
# match尝试从字符串的起始位置开始匹配,
# - 如果起始位置没有匹配成功, 返回一个None;
# - 如果起始位置匹配成功, 返回一个对象;
print(re.match(pattern1, s))
matchObj = re.match(pattern2, s)
# 返回match匹配的字符串内容;
print(matchObj.group())
# **********************search**********************
# search会扫描整个字符串, 只返回第一个匹配成功的内容;
# - 如果能找到, 返回一个对象, 通过group方法获取对应的字符串;
match1Obj = re.search(pattern1, s)
print(match1Obj.group())
match2Obj = re.search(pattern2, s)
print(match2Obj.group())
3.正则表达式特殊字符
import re
# 字符类:
print(re.findall(r'[^0-9]', 'westos123westos'))
print(re.findall(r'[0-9]', 'westos123westos'))
# 特殊字符类 .
print(re.findall(r'.', 'westos\n'))
# 特殊字符类\d
print(re.findall(r'\d', '当前文章阅读量为8'))
# 等待学习匹配次数的规则
print(re.findall(r'\d', '当前文章阅读量为8000'))
# 特殊字符类\D
print(re.findall(r'\D', '当前文章阅读量为8'))
# 等待学习匹配次数的规则
print(re.findall(r'\D', '当前文章阅读量为8000'))
# 特殊字符类\s, \S
print(re.findall(r'\s', '\n当前\r文章阅\t读量为8'))
# 等待学习匹配次数的规则
print(re.findall(r'\S', '\n当前\r文章阅\t读量为8'))
# 特殊字符类\w, \W
print(re.findall(r'\w', '12当前westos文章阅_读量为8&'))
# 等待学习匹配次数的规则
print(re.findall(r'\W', '12当前westos文章阅_读量为8&'))
4.指定字符出现指定次数
匹配字符出现次数:
: 代表前一个字符出现0次或者无限次; d, .*
+: 代表前一个字符出现一次或者无限次; d+
?: 代表前一个字符出现1次或者0次; 假设某些字符可省略, 也可以不省略的时候使用
第二种方式:
{m}: 前一个字符出现m次;
{m,}: 前一个字符至少出现m次; * == {0,}; + ==={1,}
{m,n}: 前一个字符出现m次到n次; ? === {0,1}
import re
# print(re.findall(r'd*', ''))
# print(re.findall(r'd*', 'ddd'))
# print(re.findall(r'd*', 'dwww'))
# print(re.findall(r'.*', 'westos'))
#
#
#
# print(re.findall(r'd+', ''))
# print(re.findall(r'd+', 'ddd'))
# print(re.findall(r'd+', 'dwww'))
# print(re.findall(r'd+', 'westos'))
#
#
# print(re.findall(r'188-?', '188 6543'))
# print(re.findall(r'188-?', '188-6543'))
# print(re.findall(r'188-?', '148-6543'))
# 188 6754 7645 \d{3} \d{4} \d{4}
# 18867547645
# 188-6754-7645
pattern = r'\d{3}[\s-]?\d{4}[\s-]?\d{4}'
print(re.findall(pattern,'188 6754 7645'))
print(re.findall(pattern,'18867547645'))
print(re.findall(pattern,'188-6754-7645'))
5.匹配所有的ip地址
import re
pattern = r'[1-9]\d{0,2}\.[1-9]\d{0,2}\.[1-9]\d{0,2}\.[1-9]\d{0,2}'
print(re.findall(pattern, '172.25.0.2'))
print(re.findall(pattern, '172.25.1.2'))
print(re.findall(pattern, '172.25.1.278'))
# | 代表或者的意思
pattern1 = r'^(25[0-5]|2[0-4]\d|[0-1]\d{2}|[1-9]?\d)\.(25[0-5]|2[0-4]\d|[0-1]\d{2}|[1-9]?\d)\.(25[0-5]|2[0-4]\d|[0-1]\d{2}|[1-9]?\d)\.(25[0-5]|2[0-4]\d|[0-1]\d{2}|[1-9]?\d)$'
# print(re.findall(pattern1, '172.25.1.278'))
# print(re.findall(pattern1, '172.25.1.178'))
Obj = re.match(pattern1, '172.25.1.178')
if Obj:
print("查找到匹配的内容:", Obj.group())
else:
print('No Found')
Obj = re.match(pattern1, '172.25.1.278')
if Obj:
print("查找到匹配的内容:", Obj.group())
else:
print('No Found')
6.获取贴吧总页数
from itertools import chain
from urllib.request import urlopen
import re
def getPageContent(url):
"""
获取网页源代码
:param url: 指定url内容
:return: 返回页面的内容(str格式)
"""
with urlopen(url) as html:
return html.read().decode('utf-8')
def parser_page(content):
"""
根据内容获取所有的贴吧总页数;
:param content: 网页内容
:return: 贴吧总页数
"""
pattern = r'<span class="red">(\d+)</span>'
data = re.findall(pattern, content)
return data[0]
def parser_all_page(pageCount):
"""
根据贴吧页数, 构造不同的url地址;并找出所有的邮箱
:param pageCount:
:return:
"""
emails = []
for page in range(int(pageCount)):
url = 'http://tieba.baidu.com/p/2314539885?pn=%d' %(page+1)
print("正在爬取:%s" %(url))
content = getPageContent(url)
# pattern = r'\w[-\w.+]*@[A-Za-z0-9][-A-Za-z0-9]+\.+[A-Za-z]{2,14}'
pattern = r'[a-zA-Z0-9][-\w.+]*@[A-Za-z0-9][-A-Za-z0-9]+\.+[A-Za-z]{2,14}'
findEmail = re.findall(pattern, content)
print(findEmail)
emails.append(findEmail)
return emails
def main():
url = 'http://tieba.baidu.com/p/2314539885'
content = getPageContent(url)
pageCount = parser_page(content)
emails = parser_all_page(pageCount)
print(emails)
with open('tiebaEmail.txt', 'w') as f:
for tieba in chain(*emails):
f.write(tieba + '\n')
main()
7.正则中需要转义的字符
因为这些字符在正则中有特殊含义, 所有必须转义: \., \+, \?, \*
表示分组:
| : 匹配| 左右任意一个表达式即可;
(ab): 将括号中的字符作为一个分组
\num: 引用分组第num个匹配到的字符串
(?P): 分组起别名
匹配IP:
pattern = r'([1-9]\d{0,2}\.){3}[1-9]\d{0,2}'
import re
# 当使用分组时, findall方法只能获取到分组里面的内容;
print(re.findall(r'(westos|hello)\d+', 'westos1hello2'))
pattern = r'<span class="red">(\d+)</span>'
s = '<span class="red">31</span>'
print(re.findall(pattern, s))
#
pattern = r'(<span class="red">(\d+)</span>)'
s = '<span class="red">31</span>'
print(re.findall(pattern, s))
print(re.findall(r'((westos|hello)\d+)', 'westos1hello2'))
# findall不能满足时, 考虑使用search 或者match
Obj = re.search(r'(westos|hello)(\d+)', 'westos1hello2')
if Obj:
print(Obj.group())
print(Obj.groups())
else:
print('Not Found')
# 匹配IP
pattern = r'(([1-9]\d{0,2}\.){3}[1-9]\d{0,2})'
print(re.findall(pattern, '172.25.0.3'))
print(re.findall(pattern, '172.25.3.3')[0][0])
# \num
s = '<html><title>西部开源技术中心</title></html>'
# 目前有三个分组, \1: 代指第一个分组的内容, \2: 代指第一个分组的内容,
pattern = r'<(\w+)><(\w+)>(\w+)</\w+></\w+>'
print(re.findall(pattern, s))
s = '<html><title>西部开源技术中心</tite></html>'
# 目前有三个分组, \1: 代指第一个分组的内容, \2: 代指第一个分组的内容,
pattern = r'<(\w+)><(\w+)>(\w+)</\2></\1>'
print(re.findall(pattern, s))
#
# s1 = 'http://www.westos.org/linux/book/'
# s2 = 'http://www.westos.org/python/videos/'
# s3 = 'http://www.westos.org/java/book/'
# s4 = 'http://www.westos.org/web/book/'
s1 = 'http://www.westos.org/linux/book/'
pattern = 'http://[\w\.]+/(?P<courseName>\w+)/(?P<courseType>\w+)/'
# print(re.findall(pattern, s1))
Obj = re.match(pattern, s1)
if Obj:
print(Obj.group())
print(Obj.groups())
print(Obj.groupdict())
else:
print('Not Found')
# 身份证号: 610 897 19900415 4534
s = '610897199004154534'
pattern = r'(?P<Province>\d{3})[\s-]?(?P<City>\d{3})[\s-]?(?P<Year>\d{4})[\s-]?' \
r'(?P<Month>\d{2})(?P<Day>\d{2})(\d{4})'
Obj = re.search(pattern, s)
if Obj:
print(Obj.groupdict())
else:
print('Not Found')
8.爬取单个图片
from urllib.request import urlopen
url = 'http://imgsrc.baidu.com/forum/w%3D580/sign=e23a670db9b7d0a27bc90495fbee760d/38292df5e0fe9925f33f62ef3fa85edf8db17159.jpg'
# 1. 获取图片的内容
content = urlopen(url).read()
# 2. 写入本地文件
with open('hello.jpg', 'wb') as f:
f.write(content)
9.爬取指定页贴吧图片
import re
from urllib.request import urlopen
def get_content(url):
"""
获取网页内容
:param url:
:return:
"""
with urlopen(url) as html:
return html.read()
def parser_get_img_url(content):
"""
解析贴吧内容, 获取所有风景图片的url
:param content:
:return:
"""
pattern = r'<img class="BDE_Image".*?src="(http://.*?\.jpg)".*?>'
imgUrl = re.findall(pattern, content.decode('utf-8').replace('\n', ' '))
return imgUrl
def main():
url = 'http://tieba.baidu.com/p/5437043553'
content = get_content(url)
imgLi = parser_get_img_url(content)
for index,imgurl in enumerate(imgLi):
# 根据图片的url获取每个图片的内容;
content = get_content(imgurl)
with open('img/%s.jpg' %(index+1), 'wb') as f:
f.write(content)
print("第%s个图片下载成功...." %(index+1))
# main()
import pdfkit
pdfkit.from_url('http://www.baidu.com', 'out.pdf')
10.正则与批量替换和批量分隔分离
import re
ip = '172.25.254.250'
print(ip.split('.'))
s = '12+13-15/16'
print(re.split(r'[\+\-\*/]', s))
#
s = 'westos is a company'
print(s.replace('westos', 'fentiao'))
# 希望替换的时数字, 但数字的值不固定, 则通过正则来实现;
s = "本次转发数为100"
print(re.sub(r'\d+', '0', s))
# 自动会给addNum传递一个参数, 参数时匹配到的SRE对象
def addNum(sreObj):
"""在原有基础上加1"""
# 年末任情况字符串中匹配到的内容还是字符串
num = sreObj.group() # ‘100’ ‘99’
new_num = int(num) + 1
return str(new_num)
s1 = "本次转发数为100, 分享数量为99"
print(re.sub(r'\d+', addNum, s1))