文章目录
- 1.1 行定位符
- 1.2 元字符
- 1.3 重复
- 1.4 字符类
- 1.5 排除字符
- 1.6 选择字符
- 1.7 转义字符 \
- 1.8 分组()
- 1.9 在Python中使用正则表达式
- 1.使用match()方法进行匹配
- 2.使用search()方法进行匹配语法
- 3.使用findall()方法进行匹配语法
- 2.2 替换字符串
- 2.3 使用正则表达式分割字符串
一、正则表达式语法
1.1 行定位符
1.2 元字符
. | 匹配除了换行符以外的任意字符 |
\w | 匹配字母或数字或下划线或汉字 |
\s | 匹配任意的空白符 |
\d | 匹配数字 |
^ | 匹配字符串的开始 |
$ | 匹配字符串的结束 |
1.3 重复
? | 匹配前面的字符0次或者一次 |
+ | 匹配前面的字符一次或者多次 |
* | 匹配前面字符0次或者多次 |
{n} | 匹配前面的字符n次 |
{n,} | 匹配前面的字符至少n次 |
{n,m} | 匹配起码面的字符至少n次,最多m次 |
1.4 字符类
就是说匹配一个未知的一个元组集合该怎么办—》使用中括号
比如匹配0123456789的集合就可以用[0-9]
匹配u、i、o的集合就可以用[uio]
匹配任意一个汉字[\u4e00-\u9fa5]
匹配多个[\u4e00-\u9fa5] +
1.5 排除字符
在中括号里面使用^ 就可以了
^ 表示匹配字符串的开始位置 (例外 用在中括号中[ ] 时,可以理解为取反,表示不匹配括号中字符串)
比如不匹配0123456789的集合就可以用[^0-9]
不匹配u、i、o的集合就可以用[^uio]
1.6 选择字符
|
比如身份证是15位或者18位 如果是18位,前面17位都是数字,后面一位可能是X或者x或者数字
(^\d{15}$)|(^\d{17}$)|(^\d{18}$)|(\d|X|x)$
1.7 转义字符 \
1.8 分组()
改变作用域的范围
比如(thir|four)th
不使用用小阔号匹配的是 thir 或者是fourth
使用用小阔号匹配的是 thirth 或者是fourth
1.9 在Python中使用正则表达式
1.匹配的不是一个字母
‘[^a-zA-Z]’
2.匹配的单词要用没开头
错误写法–》‘\bm\w*\b’ 因为转化为模式字符串不能直接用要转义
正确写法—》‘\bm\w*\b’ 由于模式字符串可能需要大量的反斜杠和特殊字符 ,所以可以使用另一种写法 ----》r‘\bm\w*\b’
二、使用re模块实现正则表达式操作
2.1 匹配字符串
1.使用match()方法进行匹配
语法
re.match(pattern,string,[flags])
从字符串的开始出进行匹配,成功返回Match对象,否则返回None
- pattern:表示模式字符串,由正则表达式转化而来
- string:要匹配的字符串
- flags:可选参数,表示标志位,用于控制匹配方法,比如是否区分大小写
常用flags
标志 | 说明 |
A或ASCAII | 对于\w、\W、\b、\B、\D、\s、\S只进行ASCAII匹配 |
I或IGNORECASE | 执行不区分大小写 |
M或MULTILINE | 将^和$用于包括整个字符串的开始和结束的每一行(默认情况下,适用于整个字符串的开始和结束处) |
S或DOTALL | 使用“.”字符匹配所有字符,包括换行符 |
X或VARBOSE | 忽略模式字符串中未转移的空格和注释 |
import re
if __name__ == '__main__':
pattern=r'mr_\w+'
string1='mr_123'
string2='123_mr_'
string3='MR_123'
match=re.match(pattern,string1)
print(match)
match = re.match(pattern, string2)
print(match)
match = re.match(pattern, string3)
print(match)
match = re.match(pattern, string3,re.I)
print(match)
》》》
<re.Match object; span=(0, 6), match='mr_123'>
None
None
<re.Match object; span=(0, 6), match='MR_123'>
import re
if __name__ == '__main__':
pattern = r'mr_\w+'
string1 = 'mr_123mr_123'
match = re.match(pattern, string1)
print(match)
print('匹配的开始位置:', match.start())
print('匹配的结束位置:', match.end())
print('匹配位置的元组:', match.span())
print('要匹配的字符串:', match.string)
print('匹配的数据:', match.group())
》》》
<re.Match object; span=(0, 12), match='mr_123mr_123'>
匹配的开始位置: 0
匹配的结束位置: 12
匹配位置的元组: (0, 12)
要匹配的字符串: mr_123mr_123
匹配的数据: mr_123mr_123
2.使用search()方法进行匹配语法
re.search(pattern,string,[flags])
从字符串的开始出进行匹配,成功返回Match对象,否则返回None
- pattern:表示模式字符串,由正则表达式转化而来
- string:要匹配的字符串
- flags:可选参数,表示标志位,用于控制匹配方法,比如是否区分大小写
import re
if __name__ == '__main__':
pattern=r'mr_\w+'
string1='mr_123'
string2='123_mr_'
string3='MR_123'
match=re.search(pattern,string1)
print(match)
match = re.search(pattern, string2)
print(match)
match = re.search(pattern, string3)
print(match)
match = re.search(pattern, string3,re.I)
print(match)
》》》
<re.Match object; span=(0, 6), match='mr_123'>
None
None
<re.Match object; span=(0, 6), match='MR_123'>
3.使用findall()方法进行匹配语法
re.findall(pattern,string,[flags])
从字符串的开始出进行匹配,成功返回Match对象,否则返回None
- pattern:表示模式字符串,由正则表达式转化而来
- string:要匹配的字符串
- flags:可选参数,表示标志位,用于控制匹配方法,比如是否区分大小写
import re
if __name__ == '__main__':
pattern = r'mr_\w+'
string1 = 'mr_123 mr_123'
match = re.findall(pattern, string1)
print(match)
for item in match:
print(item)
》》》
['mr_123', 'mr_123']
mr_123
mr_123
2.2 替换字符串
re.sub(pattern,repl,string,count,[flags])
- pattern:表示模式匹配字符串,由正则表达式转化而来
- repl:表示替换的字符串
- string:表示查找替换的原始字符串
- count:可选参数,表示替换的最大次数,默认所有即为0
- flags:可选参数,表示为标志,用于控制方法,比如区分大小写
import re
if __name__ == '__main__':
pattern = r'mr_\w+'
string1 = 'mR_123 mr_123'
match = re.sub(pattern,'XXXXXX',string1)
print(match)
》》》
mR_123 XXXXXX
2.3 使用正则表达式分割字符串
re.split(pattern,string,[maxsplit],[flags])
- pattern:表示模式匹配字符串,由正则表达式转化而来
- string:表示查找替换的原始字符串
- maxsplit:可选参数,表示最大的拆分次数
- flags:可选参数,表示为标志,用于控制方法,比如区分大小写
import re
if __name__ == '__main__':
pattern = r'[?|&]'
\
match=re.split(pattern,string1)
print(match)
print('--------------------------------')
for item in match:
print(item)
》》》
\
--------------------------------
\
spm=1010.2135.3001.5343
三、实战
仅供学习,切勿用于不正当行为
使用.*?
匹配任意字符
使用(.*?)
将结果输出
这里使用 ex = '<div class="thumb">.*?<img src="(.*?)" alt.*?</div>'
分析:
-
先筛选<div class="thumb">.*?</div> 筛选出内容
-
再一次筛选第一次筛选的内容<img src="(.*?)"
- 将第二步用
.*?
包含起来
#!/usr/bin/env python
# -*- coding:utf-8 -*-
import requests
import re
import os
#需求:爬取糗事百科中糗图板块下所有的糗图图片
if __name__ == "__main__":
#创建一个文件夹,保存所有的图片
if not os.path.exists('./qiutuLibs'):
os.mkdir('./qiutuLibs')
url = 'https://www.qiushibaike.com/pic/'
headers = {
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36'
}
#使用通用爬虫对url对应的一整张页面进行爬取
page_text = requests.get(url=url,headers=headers).text
#使用聚焦爬虫将页面中所有的糗图进行解析/提取
ex = '<div class="thumb">.*?<img src="(.*?)" alt.*?</div>'
img_src_list = re.findall(ex,page_text,re.S)
# print(img_src_list)
for src in img_src_list:
#拼接出一个完整的图片url
src = 'https:'+src
#请求到了图片的二进制数据
img_data = requests.get(url=src,headers=headers).content
#生成图片名称
img_name = src.split('/')[-1]
#图片存储的路径
imgPath = './qiutuLibs/'+img_name
with open(imgPath,'wb') as fp:
fp.write(img_data)
print(img_name,'下载成功!!!')