re模块

import  re
#博客截图
# 数字字母下划线
print(re.findall('w','egon 123 + _ - *'))
# 非数字字母下划线
print(re.findall('W','egon 123 + _ - *'))
#匹配空白字符
print(re.findall('s','ego	n 12
3 + _ - *'))
#匹配非空字符
print(re.findall('S','egon 123 + _ - *'))
#匹配任意数字
print(re.findall('d','egon 123 + _ - *'))
#匹配任意非数字
print(re.findall('D','egon 123 + _ - *'))
#只匹配	
print(re.findall('	','ego	n 12
3 + _ - *'))
#只匹配

print(re.findall('
','ego	n 12
3 + _ - *'))
#匹配字符串的开头^
print(re.findall('^e','ego	n 12hello
3 + _ - *'))
#匹配字符串的结尾$
print(re.findall('o$','ego	n 12hello
3 + _ - *'))


# . ?  +  *  {m,n}
# . 代表任意字符
print(re.findall('a.b','a1b a a-b aaaaab'))
# . 不能匹配
  要加re.DOTALL
print(re.findall('a.b','a
b a a-b aaaaab',re.DOTALL))

# ?左边的一个字符出现0次或1次
print(re.findall('ab?','a ab abb abbb a1b'))

# *代表左边的一个字符出现0次或者无穷次
print(re.findall('ab*','a ab abb abbb a1b'))

# + 代表左边的一个字符出现1次或者无穷次
print(re.findall('ab*','a ab abb abbb a1b'))

#{m,n} 代表左边的一个字符出现m次到n次
print(re.findall('ab{0,1}','a ab abb abbb a1b'))
print(re.findall('ab{0,}','a ab abb abbb a1b'))
print(re.findall('ab{1,}','a ab abb abbb a1b'))
print(re.findall('ab{2,4}','a ab abb abbb a1b'))

#.* 代表  贪婪匹配
print(re.findall('a.*b','jjhfh12ahhjjbwwwb'))

# .*?  非贪婪匹配 找到最近的b就结束
print(re.findall('a.*?b','jjhfh12ahhjjbwwwb'))

#.+? 表示匹配任意字符一个或则多个
#.*? 表示匹配任意字符0个或多个
print(re.findall('a.+?b','ab'))  # 匹配不到 至少要有一个
print(re.findall('a.*?b','ab'))  # 能匹配到

# | 或者
print(re.findall('compan(y|iness)','too many companiness have gone bankrupt,and the next one is my company'))
print(re.findall('compan(?:y|iness)','too many companiness have gone bankrupt,and the next one is my company'))

# rawstring:
print(re.findall(r'a\c','ac a1c abc'))  # a\c->ac

#[]取中括号内任意字符
print(re.findall('a[a-z]b','axb azb aAb a1b a-b a+b'))
print(re.findall('a[A-Z]b','axb azb aAb a1b a-b a+b'))
print(re.findall('a[a-zA-Z]b','axb azb aAb a1b a-b a+b'))
print(re.findall('a[0-9]b','axb azb aAb a1b a-b a+b'))
print(re.findall('a[-+*/]b','axb azb aAb a1b a-b a+b'))
# 上尖号 ^  组内使用为取反的意思
print(re.findall('a[^-+*/]b','axb azb aAb a1b a-b a+b'))

#re 模块的其它方法
# re.search  # 匹配不到返回None 找到一次就停止
print(re.search('a[*]b','azb axb aAb a1b a-b a+b'))
print(re.search('a[0-9]b','azb axb aAb a1b a2b a-b a+b').group())


# re.match  #  相当于在search的正则前面加上尖号 匹配不到返回None 找到一次就停止
print(re.match('a[0-9]b','azb axb aAb a1b a2b a-b a+b'))
print(re.match('a[0-9]b','a1b axb aAb a1b a2b a-b a+b').group())
print(re.search('^a[0-9]b','a1b axb aAb a1b a2b a-b a+b').group())

# re.split 以正则表达式切分
print(re.split(':','root:x:0:0::/root/bin/bash'))
'root:x:0:0::/root/bin/bash'.split(':')

#re.sub  替换
print(re.sub('root','admin','root:x:0:0::/root/bin/bash'))

#re.compile  正则复用
obj = re.compile('ad{2}b')
print(obj.findall('a12b a123b a1234b abb'))
print(obj.search('a12b a123b a1234b abb').group())

1.常用匹配符

'.'     默认匹配除
之外的任意一个字符,若指定flag DOTALL,则匹配任意字符,包括换行
'^'     匹配字符开头,若指定flags MULTILINE,这种也可以匹配上(r"^a","
abc
eee",flags=re.MULTILINE)
'$'     匹配字符结尾,或e.search("foo$","bfoo
sdfsf",flags=re.MULTILINE).group()也可以
'*'     匹配*号前的字符0次或多次,re.findall("ab*","cabb3abcbbac")  结果为['abb', 'ab', 'a']
'+'     匹配前一个字符1次或多次,re.findall("ab+","ab+cd+abb+bba") 结果['ab', 'abb']
'?'     匹配前一个字符1次或0次
'{m}'   匹配前一个字符m次
'{n,m}' 匹配前一个字符n到m次,re.findall("ab{1,3}","abb abc abbcbbb") 结果'abb', 'ab', 'abb']
'|'     匹配|左或|右的字符,re.search("abc|ABC","ABCBabcCD").group() 结果'ABC'
'(...)' 分组匹配,re.search("(abc){2}a(123|456)c", "abcabca456c").group() 结果 abcabca456c


'A'    只从字符开头匹配,re.search("Aabc","alexabc") 是匹配不到的
''    匹配字符结尾,同$
'd'    匹配数字[0-9]
'D'    匹配非数字
'w'    匹配[A-Za-z0-9]
'W'    匹配非[A-Za-z0-9]
's'     匹配空白字符、	、
、
 , re.search("s+","ab	c1
3").group() 结果 '	'

2.常用的匹配语法

'''
re模块三种比较重要的方法:
    - findall(): ----> []
        可以匹配 "所有字符" ,拿到返回的结果,返回的结果是一个列表。
        'awfwaghowiahioawhio'  # a
        ['a', 'a', 'a', 'a']
        
    - search():----> obj ----> obj.group()
        'awfwaghowiahioawhio'  # a
        在匹配一个字符成功后,拿到结果后结束,不往后匹配。
        'a'
    
    - match():----> obj ----> obj.group()
        'awfwaghowiahioawhio'  # a
        'a'
        'wfwaghowiahioawhio'  # a
         None
        从匹配字符的开头匹配,若开头不是想要的内容,则返回None。
'''
re.match 从头开始匹配
re.search 匹配包含
re.findall 把所有匹配到的字符放到以列表中的元素返回
re.splitall 以匹配到的字符当做列表分隔符
re.sub      匹配字符并替换
- ^$: 配合使用叫做精准匹配,如何限制一个字符串的长度或者内容。
- |: 或。ab|abc如果第一个条件成立,则abc不会执行,怎么解决,针对这种情况把长的写在前面就好了,一定要将长的放在前面。
- [^...]: 表示取反的意思。
- [^ab]: 代表只去ab以外的字符。
- [^a-z]: 取a-z以外的字符

3. 实例

import re
str1 = 'sean tank Ason'
#findall
res = re.findall('[a-s]{4}', str1)  # 从字符串依次取出4个
print(res)  # ['sean', 'tank', 'json']

# search
res = re.search('[a-z]{4}', str1)   #找到就结束
print(res)
print(res.group())

# match
res = re.match('sean', str1)
print(res)
print(res.group())
if res:
    print(res.group())


结果:
['sean']
<_sre.SRE_Match object; span=(0, 4), match='sean'>
sean
<_sre.SRE_Match object; span=(0, 4), match='sean'>
sean
sean

4.爬虫实例

'''
爬取豆瓣TOP250电影信息

    第1页:
        https://movie.douban.com/top250?start=0&filter=

    ...

    第9页:
        https://movie.douban.com/top250?start=200&filter=

    第10页:
        https://movie.douban.com/top250?start=225&filter=

爬蟲四部原理:
    1.发送请求: requests
    2.获取响应数据: 对方机器直接返回的
    3.解析并提取想要的数据: re
    4.保存提取后的数据: with open()

爬蟲三部曲:
    1.发送请求
    2.解析数据
    3.保存数据


# 往10个链接发送请求获取响应数据
    - requests模块 ---》 请求库
'''
import requests
import re


# 爬蟲三部曲:
# 1.发送请求
def get_page(url):
    response = requests.get(url)
    # response.content  # 获取二进制流数据,比如图片、视频、音频
    # response.text  # 获取响应文本,比如html代码
    return response


# 2.解析数据
# 伪代码:
# response = get_page('url地址')
# parser_page(response.text)
def parser_page(text):  # response.text
    # re.findall('正则表达式', '过滤的文本')
    res_list = re.findall(
        '<div class="item">.*?<a href="(.*?)">.*?<span class="title">(.*?)</span>.*?<span class="rating_num".*?>(.*?)</span>.*?<span>(.*?)人评价',
        text,
        re.S)

    for movie_tuple in res_list:
        # print(movie_tuple)
        yield movie_tuple


# 3.保存数据
# 伪代码:
# res_list = parser_page(text)
# save_data(res_list)
def save_data(res_list_iter):
    with open('douban.txt', 'a', encoding='utf-8') as f:
        for movie_tuple in res_list_iter:
            movie_url, movie_name, movie_point, movie_num = movie_tuple
            # 写入文件前的模样
            str1 = f'''
            电影地址: {movie_url} 
            电影名字: {movie_name} 
            电影评分: {movie_point} 
            评价人数: {movie_num} 
            '''
            f.write(str1)


# 获取10个链接
n = 0
for line in range(10):
    url = f'https://movie.douban.com/top250?start={n}&filter='
    n += 25
    print(url)

    response = get_page(url)
    res_list_iter = parser_page(response.text)
    # print(res_list_iter)
    save_data(res_list_iter)

输出结果:

https://movie.douban.com/top250?start=0&filter=
https://movie.douban.com/top250?start=25&filter=
https://movie.douban.com/top250?start=50&filter=
https://movie.douban.com/top250?start=75&filter=
https://movie.douban.com/top250?start=100&filter=
https://movie.douban.com/top250?start=125&filter=
https://movie.douban.com/top250?start=150&filter=
https://movie.douban.com/top250?start=175&filter=
https://movie.douban.com/top250?start=200&filter=
https://movie.douban.com/top250?start=225&filter=

原文地址:https://www.cnblogs.com/bigbox/p/11892364.html