常用模块re

re模块

import re

讲正题之前我们先来看一个例子:https://reg.jd.com/reg/person?ReturnUrl=https%3A//www.jd.com/

这是京东的注册页面,打开页面我们就看到这些要求输入个人信息的提示。
假如我们随意的在手机号码这一栏输入一个11111111111,它会提示我们格式有误。
这个功能是怎么实现的呢?
假如现在你用python写一段代码,类似:

phone_number = input('please input your phone number : ')

你怎么判断这个phone_number是合法的呢?

根据手机号码一共11位并且是只以13、14、15、18开头的数字这些特点,我们用python写了如下代码:

img

[复制代码](javascript:void(0)😉

while True:
    phone_number = input('please input your phone number : ')
    if len(phone_number) == 11 \
            and phone_number.isdigit()\
            and (phone_number.startswith('13') \
            or phone_number.startswith('14') \
            or phone_number.startswith('15') \
            or phone_number.startswith('18')):
        print('是合法的手机号码')
    else:
        print('不是合法的手机号码')

[复制代码](javascript:void(0)😉

这是你的写法,现在我要展示一下我的写法:

img

import re
phone_number = input('please input your phone number : ')
if re.match('^(13|14|15|18)[0-9]{9}$',phone_number):
        print('是合法的手机号码')
else:
        print('不是合法的手机号码')

对比上面的两种写法,此时此刻,我要问你你喜欢哪种方法呀?你肯定还是会说第一种,为什么呢?因为第一种不用学呀!
但是如果现在有一个文件,我让你从整个文件里匹配出所有的手机号码。你用python给我写个试试?
但是学了今天的技能之后,分分钟帮你搞定!

今天我们要学习python里的re模块和正则表达式,学会了这个就可以帮我们解决刚刚的疑问。正则表达式不仅在python领域,在整个编程届都占有举足轻重的地位。

不管以后你是不是去做python开发,只要你是一个程序员就应该了解正则表达式的基本使用。如果未来你要在爬虫领域发展,你就更应该好好学习这方面的知识。
但是你要知道,re模块本质上和正则表达式没有一毛钱的关系。re模块和正则表达式的关系 类似于 time模块和时间的关系
你没有学习python之前,也不知道有一个time模块,但是你已经认识时间了 12:30就表示中午十二点半(这个时间可好,一般这会儿就该下课了)。
时间有自己的格式,年月日时分秒,12个月,365天......已经成为了一种规则。你也早就牢记于心了。time模块只不过是python提供给我们的可以方便我们操作时间的一个工具而已

re模块下的常用方法

findall()

search()

import re
# ret = re.findall('\d+','23423klkj234234klj4345lk')
# print(ret) #返回所有匹配到的,以列表形式['23423', '234234', '4345']

# ret = re.search('\d+','19740ash93010uru')
# print(ret)  # 变量
# if ret:
#     print(ret.group())
# ret = re.search('\d+','23423klkj234234klj4345lk')
# print(ret) #变量 <re.Match object; span=(0, 5), match='23423'>
# if ret:
#     print(ret.group()) #23423
# findall 还是按照完整的正则进行匹配,只是显示括号里匹配到的内容
# ret = re.findall('9\d\d','19740ash93010uru')
# print(ret)

# search 还是按照完整的正则进行匹配,显示也显示匹配到的第一个内容,但是我们可以通过给group方法传参数
# 来获取具体文组中的内容
# ret = re.search('9(\d)(\d)','19740ash93010uru')
# print(ret)  # 变量
# if ret:
#     print(ret.group())
#     print(ret.group(1))
#     print(ret.group(2))

# findall
    # 取所有符合条件的,优先显示分组中的
# search 只取第一个符合条件的,没有优先显示这件事儿
    # 得到的结果是一个变量
        # 变量.group() 的结果 完全和 变量.group(0)的结果一致
        # 变量.group(n) 的形式来指定获取第n个分组中匹配到的内容
为什么在search中不需要分组优先 而在findall中需要?

加上括号 是为了对真正需要的内容进行提取
ret = re.findall('<\w+>(\w+)</\w+>','<h1>askh930s02391j192agsj</h1>')
print(ret)

search
ret = re.search('<(\w+)>(\w+)</\w+>','<h1>askh930s02391j192agsj</h1>')
print(ret.group())
print(ret.group(1))
print(ret.group(2))

如果我们要查找的内容在一个复杂的环境中
我们要查的内容并没有一个突出的 与众不同的特点 甚至会和不需要的杂乱的数据混合在一起
这个时候我们就需要把所有的数据都统计出来,然后对这个数据进行筛选,把我们真正需要的数据对应的正则表达式用()圈起来
这样我们就可以筛选出真正需要的数据了

# 分组和findall的现象
    # 为什么要用分组?
        # 把想要的内容放分组里
# 如何取消分组优先
    # 如果在写正则的时候由于不得已的原因 导致不要的内容也得写在分组里
    # (?:)  取消这个分组的优先显示
# split 分割
ret1 = re.split('\d+','alex222wusir')
ret2 = re.split('\d(\d)\d','alex123wusir')
print(ret1)#['alex', 'wusir']
print(ret2)#['alex', '2', 'wusir']
# sub  替换
ret1 = re.sub('\d+','H','alex123wusir456',1)
print(ret1)#alexHwusir456

# subn
ret2 = re.subn('\d+','H','alex123wusir456')
print(ret2)#('alexHwusirH', 2)
# match  用户输入的内容匹配的时候,要求用户输入11位手机号码,^手机号正则$
# match('手机号正则$','123eva456taibai')  规定这个字符号必须是什么样的
# search('^手机号正则$','123eva456taibai') 用来寻找这个字符串中是不是含有满足条件的子内容

# ret = re.match('\d+','123eva456taibai')
# print(ret.group())
# compile -- 节省代码时间的工具
    # 假如同一个正则表达式要被使用多次
    # 节省了多次解析同一个正则表达式的时间
ret = re.compile('\d+')
res1 = ret.search('alex37176')
res2 = ret.findall('alex37176')
print(res1)#<re.Match object; span=(4, 9), match='37176'>
print(res2)#['37176']
# finditer -- 节省空间
# ret = re.finditer('\d+','agks1ak018093')
# for i in ret:
#     print(i.group())

#     1
#     018093
# 先compile(如果没有重复使用同一个正则,也不能节省时间)
# 再finditer
ret= re.compile('\d+')
res = ret.finditer('agks1ak018as093')
for r in res:
    print(r.group())
posted @ 2020-06-12 17:24  爱浪的跳蚤  阅读(106)  评论(0编辑  收藏  举报