其他分享
首页 > 其他分享> > 爬虫--03:正则表达式

爬虫--03:正则表达式

作者:互联网

Reptilien 03: regulären ausdruck

正则表达式

在这里插入图片描述

一、正则表达式的简介

1、 概念

2、正则表达式的应用场景

二、正则表达式对python的支持

1、普通字符

2、match()函数

import re
'''
pattern--->正则表达式:如果匹配成功,则返回一个match对象,否则返回一个None
string--->需要匹配的数据
flags=0--->标致位:控制正则表达式的匹配方式(是否需要换行匹配,是否区分大小写......)

# match函数只能从开头匹配,不能从其他位置匹配
'''
# re.match(pattern, string, flags=0)
s = 'python and java'
pattern = 'python'  # 正则表达式
result = re.match(pattern, s)
if result:
    # print(result) # 返沪:<re.Match object; span=(0, 6), match='python'>
    print(result.group()) # 返沪:python
else:
    print('没有匹配!')

3、元字符

4、预定义匹配字符集

import re

'''
01:\d--表示匹配0-9当中的任意一个字符
'''
result1 = re.match(r'\d', '123').group()
print(result1)
'''
02:\w--表示匹配任意一个字母或数字或下划线,即0-9、a-z、A-Z
'''
result2 = re.match(r'\w', '123').group()
print(result2)
result3 = re.match(r'\w', 'a123').group()
print(result3)
result4 = re.match(r'\w', 'A123').group()
print(result4)
'''
03:\s--表示匹配空格、制表符、其他的一些空白
'''
result5 = re.match(r'\s', ' ').group()
print(result5)
'''
04:\D(\d的反集--表示非数字当中的任意一个
'''
result6 = re.match(r'速度与激情\D', '速度与激情a').group()
print(result6)
'''
05:\W(\w的反集)--表示匹配一些特殊符号
'''
result7 = re.match(r'\W', '&^%%').group()
print(result7)
'''
06:\S(\s的反集)--表示匹配除了空格、制表符、其他的一些空白的任意字符
'''
result8 = re.match(r'\S', 'sdsdfasd').group()
print(result8)
result9 = re.match(r'\S', '158532').group()
print(result9)

5、重复匹配

import re

'''
# {n}:表达式重复n次。
'''
# 代码演示
result1 = re.match(r'\d{3}', '123').group()
print(result1)
result2 = re.match(r'^1[345678]\d{9}$', '15840039263').group()
print(result2)
'''
# {m,n}:表达式至少重复m次,最多重复n次。
'''
# 代码演示
result3 = re.match(r'\d{3,4}-\d{7,8}', '0123-1234567').group()
print(result3)
'''
# {m,}:表达式至少重复m次。
'''
# 代码演示
result4 = re.match(r'\d{3,}-\d{7,8}', '012-1234567').group()
print(result4)
'''
# ?:匹配表达式0次或者1次
'''
# 代码演示
result9 = re.match(r'w[a-z]?', 'wa').group()
print(result9)
result10 = re.match(r'w[a-z]?', 'wae').group()
print(result10)
'''
# +:表达式匹配至少出现1次
'''
# 代码演示
result7 = re.match(r'w[a-z]+', 'weasd').group()
print(result7)
# result8 = re.match(r'w[a-z]+', 'w').group()
# print(result8) # 报错

'''
# *:表达式出现0次到任意次,相当于{0,}
'''
# 代码演示
result5 = re.match(r'w[a-z]*', 'wfadasd').group()
print(result5)
result6 = re.match(r'w[a-z]*', 'w').group()
print(result6)

6、位置匹配与非贪婪模式

①、位置匹配

②、贪婪与非贪婪模式

import re

'''
# 贪婪匹配:以最长的结果做为返回,在python当中是默认贪婪的,总是尝试去匹配尽可能多的字符
'''
s = '<div>abc</div><div>bcd</div>'
# '''
# 需求:<div>abc</div>
# '''
ptn = '<div>.*</div>'
r = re.match(ptn, s)
print(r.group()) # <div>abc</div><div>bcd</div>


'''
# 非贪婪模式:总是尝试去匹配尽可能少的字符
# 怎么使用非贪婪模式:在.*加上?,在.+加上?或者{m, n}
'''
s = '<div>abc</div><div>bcd</div>'
'''
需求:<div>abc</div>
'''
ptn = '<div>.*?</div>'
r = re.match(ptn, s)
print(r.group())

打印输出结果:

C:\python\python.exe D:/PycharmProjects/Python大神班/day-06/01-非贪婪匹配.py
<div>abc</div><div>bcd</div>
<div>abc</div>

Process finished with exit code 0

代码演示02:正则表达式练习

import re

def fn(ptn, list):
    for x in list:
        result = re.match(ptn, x)
        if result:
            print('匹配成功!', '匹配结果是:', result.group())
        else:
            print(x, '匹配失败!')

# . :表示匹配除了换行符的任意字符
list = ['abc1', 'ab', 'aba', 'abbcd', 'other', 'another']
ptn = 'ab.'
fn(ptn, list)

# [] : 匹配中括号中列举的字符
list = ['man', 'mbn', 'mcn', 'mdn', 'mon', 'nba']
ptn = 'm[abcd]n'
fn(ptn, list)

# \d :匹配数字【0-9】
list = ['py9', 'py3', 'other', 'pyxx']
ptn = 'py\d'
fn(ptn, list)

# \D :匹配非数字的字符
list = ['py9', 'py3', 'other', 'pyxx']
ptn = 'py\D'
fn(ptn, list)

# \s :匹配空白字符
list= ['hello world', 'helloxxx', 'hello,world']
ptn = 'hello\sworld'
fn(ptn, list)

# \w :匹配单词、字母、下划线
list = ['1-age', 'a-age', '#-age', '_-age']
ptn = '\w-age'
fn(ptn, list)

# * :表示匹配出现0次或任意次
list = ['hello', 'abc', 'xxx', 'h']
ptn = 'h[a-z]*'
fn(ptn, list)

# {m} :表示匹配至少m次
list = ['hello', 'python', '^%%&%^#^$%', '123456']
ptn = '\w{6}'
fn(ptn, list)

# {m, n} :表示至少匹配m次,最多匹配n次
list = {'abcd', 'python', '*&%%*&*&', '_xxx211', '65465465'}
ptn = '\w{3, 5}'
fn(ptn, list)

# $ : 表示匹配带该字符(¥)结束
list = ['123@qq.com', 'abc@yy.com', 'bcd@qq.com.cm']
ptn = '\w+@qq.com$'
fn(ptn, list)

打印输出结果:

C:\python\python.exe D:/PycharmProjects/Python大神班/day-06/02-正则表达式练习.py
匹配成功! 匹配结果是: abc
ab 匹配失败!
匹配成功! 匹配结果是: aba
匹配成功! 匹配结果是: abb
other 匹配失败!
another 匹配失败!
匹配成功! 匹配结果是: man
匹配成功! 匹配结果是: mbn
匹配成功! 匹配结果是: mcn
匹配成功! 匹配结果是: mdn
mon 匹配失败!
nba 匹配失败!
匹配成功! 匹配结果是: py9
匹配成功! 匹配结果是: py3
other 匹配失败!
pyxx 匹配失败!
py9 匹配失败!
py3 匹配失败!
other 匹配失败!
匹配成功! 匹配结果是: pyx
匹配成功! 匹配结果是: hello world
helloxxx 匹配失败!
hello,world 匹配失败!
匹配成功! 匹配结果是: 1-age
匹配成功! 匹配结果是: a-age
#-age 匹配失败!
匹配成功! 匹配结果是: _-age
匹配成功! 匹配结果是: hello
abc 匹配失败!
xxx 匹配失败!
匹配成功! 匹配结果是: h
hello 匹配失败!
匹配成功! 匹配结果是: python
^%%&%^#^$% 匹配失败!
匹配成功! 匹配结果是: 123456
python 匹配失败!
abcd 匹配失败!
*&%%*&*& 匹配失败!
_xxx211 匹配失败!
65465465 匹配失败!
匹配成功! 匹配结果是: 123@qq.com
abc@yy.com 匹配失败!
bcd@qq.com.cm 匹配失败!

Process finished with exit code 0

三、re模块的常用方法

在这里插入图片描述

1、flag匹配模式

在这里插入图片描述

2、search(pattern, string, flags=0)函数

3、findall(pattern, string, flags=0)函数

4、split(pattern, string, maxsplit=0, flags=0)函数

5、sub(pattern, repl, string, count=0, flags=0)函数

代码演示:

import re

# compile()--根据包含的正则表达式的字符串创建模式对象,返回正则表达式对象(re对象)
pat = re.compile(r'abc')
res = pat.match('abc123').group()
print(res)
# re.I-->表示不区分大小写匹配
pat = re.compile(r'abc', re.I)
res = pat.match('ABC123').group()
print(res)

# search()--在字符串中查找,返回第一个匹配的对象或者None
r = re.search(r'abc', '123abc456abc789').group()
print(r)

# findall()--作为re模块三大搜索函数之一,findall()与match()、search()的不同指出在于,前两者都是单值匹配,找到一个就忽略后边,而findall()是全文查找,它的返回值是一个匹配到的字符串的列表。这个列表没有group()方法,没有start、end、span,更不是一个匹配对象,仅仅是个列表!如果一项都没有匹配到那么返回一个空列表
r = re.findall(r'abc', '123abc456abc789')
print(r)

# split()--re模块的split()方法和字符串的split()方法很相似,都是利用特定的字符去分割字符串。但是re模块的split()可以使用正则表达式,因此更灵活,更强大
# split有个参数maxsplit(),用于指定分割的次数
s = '8+7*5+6/3'
r = re.findall(r'\d', s)
print(r)
r = re.split(r'[\+\*\/]', s)
print(r)
# maxsplit--最大分割次数
r = re.split(r'[\+\*\/]', s, maxsplit=3)
print(r)

# sub()--sub()方法类似字符串的replace()方法,用指定的内容替换匹配到的字符,可以指定替换次数
s = 'i am wangjiaxin i am very handsome'
r = re.sub(r'i', 'I', s)
print(r)

打印输出结果:

C:\python\python.exe D:/PycharmProjects/Python大神班/day-06/03-re模块常用的方法.py
abc
ABC
abc
['abc', 'abc']
['8', '7', '5', '6', '3']
['8', '7', '5', '6', '3']
['8', '7', '5', '6/3']
I am wangjIaxIn I am very handsome

Process finished with exit code 0

四、分组功能

代码演示:反正组功能

# 分组,就是去已经匹配到的内容里面筛选出需要的内容(二次过滤)
import re
s = 'apple price is $66, banana price is $6'
'''
需求
$66
$6
'''
result = re.search('.+\$\d+.+\$\d+', s).group()
print(result)
result1 = re.search('.+(\$\d+).+(\$\d+)', s)
result2 = re.search('.+(\$\d+).+(\$\d+)', s)
print(result1.group(1))
print(result2.group(2))
print(result1.groups())
'''
print(result1.group(1))--匹配第一个分组
print(result2.group(2))--匹配第二个分组
print(result1.groups())--获取所有分组(元组形式返回)
print(result1.group())--匹配整个分组
'''

打印输出结果:

C:\python\python.exe D:/PycharmProjects/Python大神班/day-06/04-分组功能.py
apple price is $66, banana price is $6
$66
$6
('$66', '$6')

Process finished with exit code 0

练习

百度贴吧图片爬取练习

代码演示:百度贴吧图片爬取练习

import requests
import re
import json
'''
需求:爬取贴吧主题的图片
'''
# 思路:找到这些图片的URL,然后保存图片
'''
1、找到图片的url地址,但是网页源码中没有
分析:1、通过network分析数据接口。2、通过selenium进行模拟爬去数据
'''
name = 1
# 目标url
for i in range(1, 80, 39):
    url = 'https://tieba.baidu.com/photo/g/bw/picture/list?kw=%E6%B5%B7%E8%B4%BC%E7%8E%8B&alt=jview&rn=200&tid=1934517161&pn=1' + '&ps=' + str(i) + '&ps=' + str(39 + i) + '&wall_type=h&_=1612926942322'
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.104 Safari/537.36'
            }
    # 发起请求,获得响应结果
    res = requests.get(url, headers=headers).text
    img_urls = re.findall('"murl":"(.*?)"', res)
    # print(img_urls)
    for img_url in img_urls:
        print(img_url)
        print('正在下载第{}张图片'.format(name))
        # 对图片链接发起请求
        img_response = requests.get(img_url)
        # 保存图片
        with open('image/%d.jpg' %name, 'wb') as file_object:
            file_object.write(img_response.content)
        name += 1


'''
找出url规律
url1 = https://tieba.baidu.com/photo/g/bw/picture/list?kw=%E6%B5%B7%E8%B4%BC%E7%8E%8B&alt=jview&rn=200&tid=1934517161&pn=1&ps=1&pe=40&info=1&_=1612926875683

url2 = https://tieba.baidu.com/photo/g/bw/picture/list?kw=%E6%B5%B7%E8%B4%BC%E7%8E%8B&alt=jview&rn=200&tid=1934517161&pn=1&ps=40&pe=79&wall_type=h&_=1612926908798

url3 = https://tieba.baidu.com/photo/g/bw/picture/list?kw=%E6%B5%B7%E8%B4%BC%E7%8E%8B&alt=jview&rn=200&tid=1934517161&pn=1&ps=79&pe=118&wall_type=h&_=1612926942322
规律:ps=1、ps=40、ps=79
规律:pe=40、pe=79、pe=118
差值为39
'''

打印输出结果:

http://imgsrc.baidu.com/forum/wh%3D322%2C200/sign=40e5cae078f0f736d8ab440238679f2b/e5f5bc3eb13533fa690a6fb1a8d3fd1f40345b9b.jpg
正在下载第48张图片
http://imgsrc.baidu.com/forum/wh%3D321%2C200/sign=4463c55cd7ca7bcb7d2ecf2c8c384751/0b1bafc379310a558574226bb74543a98326108e.jpg
正在下载第49张图片
http://imgsrc.baidu.com/forum/wh%3D321%2C200/sign=7950ef3859ee3d6d22938fc871274110/251ec895d143ad4bf97eba5f82025aafa50f068e.jpg
正在下载第50张图片
http://imgsrc.baidu.com/forum/wh%3D322%2C200/sign=41a5ab7ff703918fd78435c9630f0aa5/1ae07b899e510fb32da68b08d933c895d0430c9b.jpg
正在下载第51张图片
http://imgsrc.baidu.com/forum/wh%3D321%2C200/sign=1153ab76f2d3572c66b794dfb8224f15/ae4bd0160924ab188ca91da835fae6cd7a890b9b.jpg
正在下载第52张图片
http://imgsrc.baidu.com/forum/wh%3D321%2C200/sign=90adcea728381f309e4c85aa9b30603a/28128794a4c27d1edc99c75b1bd5ad6edcc4389b.jpg
正在下载第53张图片

标签:03,匹配,ptn,--,爬虫,re,print,group,match
来源: https://blog.csdn.net/Rhymeplot__JDQS/article/details/113815041