re模块

re模块

1、什么是正则表达式?什么是re模块?

  (1)正则表达式:

    正则表达式是一门独立的技术,人和语言都可以使用正则表达式,

    正则表达式是由一堆特殊的字符组合而来的

      ① 元字符:

        ^:代表开头

        $:代表结束

        |:或者的意思

        ():可以获取一个值,判断是否是13或14等

        {9}:需要获取9个值

        []:分组限制取值范围,[0-9]:限制只能获取0-9的某一个字符

        参考图片:点我查看

import re

# \w:匹配字母、数字、下划线
print(re.findall("\w", 'hello 123_ */-='))    # 执行结果:['h', 'e', 'l', 'l', 'o', '1', '2', '3', '_']
# \W:匹配非字母、数字、下划线
print(re.findall("\W", 'hello 123_ */-='))    # 执行结果:[' ', ' ', '*', '/', '-', '=']
# \s:匹配任意空白字符
print(re.findall("\s", 'hell\no 12\t3_ */-='))    # 执行结果:['\n', ' ', '\t', ' ']
# \S:匹配任意非空字符
print(re.findall("\S", 'hell\no 12\t3_ */-='))    # 执行结果:['h', 'e', 'l', 'l', 'o', '1', '2', '3', '_', '*', '/', '-', '=']
# \d:匹配任意数字,等价于[0-9]
print(re.findall("\d", 'hell\no 12\t3_ */-='))    # 执行结果:['1', '2', '3']
# \D:匹配任意非数字
print(re.findall("\D", 'hell\no 12\t3_ */-='))    # 执行结果:['h', 'e', 'l', 'l', '\n', 'o', ' ', '\t', '_', ' ', '*', '/', '-', '=']
# \n:匹配一个换行符
print(re.findall("\n", 'hell\no 12\t3_ */-='))    # 执行结果:['\n']
# \t:匹配一个制表符
print(re.findall("\t", 'hell\no 12\t3_ */-='))    # 执行结果:['\t']
# 匹配特定字符
print(re.findall("l", 'hell\no 12\t3_ */-='))    # 执行结果:['l', 'l']
print(re.findall("yangy", "yangy my name is yangy, oh yangy is my big baby"))    # 执行结果:['yangy', 'yangy', 'yangy']
# ^:以什么开头
print(re.findall("^yangy", "yangy my name is yangy, oh yangy is my big baby"))    # 执行结果:['yangy']
# $:以什么结尾
print(re.findall("yangy$", "yangy my name is yangy, oh yangy is my big baby, yangy"))    # 执行结果:['yangy']

 

      ② 字符组:

        [0-9]:可以匹配到一个0-9的字符

        [9-0]:报错,必须从大到小

        [a-z]:从小写的a-z

        [A-Z]:从大写的A-Z

        [z-A]:错误,只能从小到大,根据ASCII表来匹配

        [A-z]:从大写的A到小写的z

        注意:顺序必须要按照ASCII码数值的顺序来编写

import re

res = re.match("[A-Za-z0-9]{4}", "Yang9527")
print(res)    # 默认只获取一个值,{}里面写多少就是匹配多少个值
if res:
    print("匹配成功")

  执行结果:

<re.Match object; span=(0, 4), match='Yang'>
匹配成功

 

      ③ 组合使用

        \w\W:匹配字母、数字、下划线与非字母数字、下划线,匹配所有

        \d\D:无论是数字或者非数字都可以匹配

        \t:table

        \n:换行

        \b:匹配单词结尾

        ^:startswith 以什么开头

          - '^'在外面使用:表示以什么开头

          - [^]用在[]里面:表示取反的意思

        $:endswith 以什么结尾

        ^$:配合使用叫做精准匹配,如何限制一个字符串的长度或者内容

        |:或. ab|abc如果第一个条件成立,则abc不会执行,怎么解决,针对这种情况把长的写在前面就好了,一定要将长的放在前面

        [^...]:表示取反的意思

        [^ab]:代表只取ab以外的字符

        [^a-z]:取a-z以外的字符

        (?:):表示非捕获分组,和捕获分组的唯一区别在于,非捕获分组匹配的值不会保存起来

# 将res或者y保留与compan进行拼接
print(re.findall('compan(?:ies|y)','Too many companies have gone bankrupt, and the next one is my company'))

  执行结果:

['companies', 'company']

        补充:贪婪模式和非贪婪模式

          贪婪模式:.* 往后一直匹配,匹配到最后一个符合条件的元素结束

          非贪婪模式:.*? 往后匹配到第一个符合条件的元素结束,往后继续匹配 ------> 可以拿来过滤数据

print(re.findall('a(.*)c','akjfnvkjfcdnjkngasdfcfjsknasfc'))
print(re.findall('a(.*?)c','akjfnvkjfcdnjkngasdfcfjsknasfc'))

  执行结果:

['kjfnvkjfcdnjkngasdfcfjsknasf']    # 贪婪模式
['kjfnvkjf', 'sdf', 'sf']    # 非贪婪模式

 

  (2)re模块:

    在python中,若想要使用正则表达式,必须通过re模块来实现

    import re

 

 

2、为什么要使用正则表达式?

  比如要获取一堆字符串中的某些字符,正则表达式可以过滤并提取出想要的字符数据

  应用场景:

    (1)爬虫

    (2)数据分析过滤数据

    (3)用户名密码、手机认证:检测用户输入的合法性

 

 

3、re模块中三种比较重要的方法

  (1)findall(),返回列表:

    可以匹配所有字符,拿到返回结果,返回结果是一个列表。

import re

str1 = 'bear blue hung'
res1 = re.findall('[a-z]{4}', str1)
print(res1)

  执行结果:

['bear', 'blue', 'hung']

 

  (2)search(),返回一个对象,使用.group()取出:

    在匹配一个字符成功拿到结果后结束程序,不继续往后匹配

import re

str1 = 'bear blue hung'
res2 = re.search("[a-z]{4}", str1)
print(res2.group())

  执行结果:

bear

 

  (3)match(),返回对象,使用.group()取出:

    从匹配字符的开头匹配,若开头不是想要的内容,则返回None

import re

str1 = 'bear blue hung'
res3 = re.match("[a-z]{4}", str1)
print(res3.group())

  执行结果:

bear

 

 

例:使用re模块校验手机号码的合法性

  需求:11位,开头是13/14/15/17/18/19

  ① 不使用re校验

import re

while True:
    user_number = input("请输入你的手机号:").strip()
    if len(user_number) == 11 and (user_number.startswith(
        "13"
    ) or user_number.startswith(
        "14"
    ) or user_number.startswith(
        "15"
    ) or user_number.startswith(
        "17"
    ) or user_number.startswith(
        "18"
    ) or user_number.startswith(
        "19"
    )):
        print("手机号码合法!")
        break
    else:
        print("手机号码不合法")

 

  ② 使用re校验

import re

while True:
    user_number = input("请输入你的手机号:").strip()

    # 参数1:正则表达式,参数2:需要过滤的字符串
    # ^:代表开头
    # $:代表结束
    # |:或者的意思
    # ():可以获取一个值,判断是否是13或14等
    # {9}:需要获取9个值
    # []:分组限制取值范围,[0-9]:限制只能获取0-9的某一个字符
    if re.match("^(13|14|15|17|18|19)[0-9]{9}$", user_number):
        print("手机号码合法!")
        break
    else:
        print("手机号码不合法")

  执行结果:

请输入你的手机号:12222222222
手机号码不合法
请输入你的手机号:13333333333
手机号码合法!

 

 

4、使用re模块爬取豆瓣Top250电影信息

  爬蟲四步原理:

    1.发送请求:requests

    2.获取相应数据:对方及其直接返回

    3.解析并提取想要的数据:re

    4.保存提取后的数据:with open()文件处理

 

  爬蟲三步曲:

    1.发送请求

    2.解析数据

    3.保存数据

 

注意:豆瓣网页爬虫必须使用请求头,否则服务器不予返回数据

import re
import requests

# 爬蟲三部曲:
# 1.获取请求
def get_data(url, headers):
    response = requests.get(url, headers=headers)
    # 如果爬取的是html文本就是用.text方法获取文本数据,如果爬取的是音视频就用.content方法获取二进制流数据
    # print(response.text)    # 获取相应文本,比如html代码
    return response.text

# 2.解析数据
def parser_data(text):
    # re.findall("正则表达式", "过滤的文本", re.S)  # 匹配模式:re.S 全局模式
    data = re.findall(
        '<div class="item">.*?<a href="(.*?)">.*?<span class="title">(.*?)</span>.*?<span class="rating_num" property="v:average">(.*?)</span>.*?<span>(.*?)人评价</span>', text, re.S)
    for move_info in data:
        yield move_info

# 3.保存数据
def save_data(res_list_iter):
    with open("豆瓣TOP250.txt", "a", encoding="utf-8") as f:
        for i in res_list_iter:
            move_page, move_title, move_score, move_evaluation = i
            # print(move_page, move_title, move_score, move_evaluation)
            str1 = f"电影名字:《{move_title}》   电影评分:{move_score}   电影评价:{move_evaluation}   电影详情页:{move_page}\n"
            f.write(str1)

# 使用请求头请求数据
headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 \
    Safari/537.36'
}
n = 0
# 获取10个链接
for i in range(10):
    url = f"https://movie.douban.com/top250?start={n}&filter=="
    n += 25
    text = get_data(url, headers)
    res_list_iter = parser_data(text)
    save_data(res_list_iter)
re模块爬取豆瓣Top250电影信息

执行结果:

posted @ 2020-10-19 19:46  chchcharlie、  阅读(239)  评论(0编辑  收藏  举报