正则表达式

2022.3.28正则表达式

2022.3.28日 星期一

  • 正则表达式引入
  • 正则表达式的概念
  • 正则表达式字符组
  • 正则表达式特殊符号
  • 正则表达式量词
  • 正则表达式贪婪与非贪婪匹配
  • 正则表达式取消转义
  • python内置模块之re模块

一、正则表达式引入

可以打开京东注册页面,输入手机号,会发现输入正确的手机号会显示正常,如果输入错误的手机号则会显示错误

qrWLef.png

这个如果使用我们之前学过的内容是否可以实现呢,是的

phone_num = input('输入手机号码:').strip()
if len(phone_num) == 11:  # 验证手机号码为11位
    if phone_num.isdigit():  # 判断是否为数字
        if phone_num.startwith('13') or phone_num.startwith('15') or phone_num.startwith('18')...
        #判断以什么数字开头
        ...

这里不往下过多去写,我们发现通过python代码也能实现一些功能,但是过于冗长,是否有什么能解决这种问题呢?答案是肯定的,今天学习的内容就是正则表达式,我们看一下正则表达式怎么写:

import re  # 调用re模块
phone_number = input('please input your phone number : ').strip()  # 获取用户输入
if re.match('^(13|14|15|18)[0-9]{9}$', phone_number):  # 使用正则表达式及re模块判断手机号码是否合规
    print('是合法的手机号码')
else:
    print('不是合法的手机号码')

这样短短的几行代码就解决了,是不是感觉很有趣呢

二、正则表达式的概念

正则表达式是一种独立的语言,专门用来匹配、校验、筛查所需的数据,任何编程语言都可以使用,在python中如果想用就必须借助内置模块re

概括:

利用一些“特殊符号”的组合去字符串中筛选出想要的数据

补充:在匹配筛选查找数据的时候可以使用正则提供的符号也可以直接写目标数据

三、正则表达式之字符组

在线测试网站:

http://tool.chinaz.com/regex/

字符组是用来筛选单个字符的,单个字符组默认只匹配一个字符

[0123456789]  # 匹配0到9之间的任意一个数字
[0-9]  # 上面的简写,表示数字范围
[a-z]  # 匹配字母a到z之间的任意一个小写字母
[A-Z]  # 匹配字母A到Z之间的任意一个大写字母
[0-9a-zA-Z]  # 上面所有的组合也可以

四、正则表达式之特殊符号

特殊符号也是默认一次匹配一个字符

.        匹配除换行符以外的任意字符
\w       匹配数字、字母、下划线(在筛选变量名中可能用到)
\W       匹配非字母非数字非下划线
\d       匹配任意的数字
\D       匹配任意非数字
\t       匹配一个制表符(tab键)
^        匹配字符串的最开始的字符
		eg:^9  找9且9必须在开头
$        匹配字符串的结尾
		eg:9$  找9且9必须在结尾
a|b      匹配a或b,管道符是或(or)的意思
()       给正则表达式分组并不影响正则匹配
[]       字符组的概念(里面所有的数据都是或的关系)
[^]      上箭号在中括号中是取反操作,要取反的字符跟在^的后面

五、正则表达式之量词

量词必须跟在正则表达式的后面,不能单独使用,目的是增加匹配的字符数

注意:量词默认都是贪婪匹配,即尽可能多的匹配

*        重复最少0次或最多无数次(默认就是多次,越多越好)
+        重复最少1次或最多无数次(默认就是多次,越多越好)
?        重复最少0次或最多1次(默认是1次,越多越好)
{n}      重复n次
{n,}     重复最少n次,最多无数次(越多越好)
{n,m}    重复最少n次,最多m次(越多越好)

身份证号小练习:

身份证号码是一个长度为15或18个字符的字符串,如果是15位则全部由数字组成,首位不能为0;如果是18位,则前17位全部是数字,末位可能是数字或x

^[1-9][0-9]{14}  # 15位身份证号
^[1-9][0-9]{16}[1-9x]  # 18位身份证号

还有一些比如校验邮箱、快递单号、座机号等,很多常见的不需要我们编写,直接百度查找即可,但是前提是自己能看懂别人写的大概意思

六、取消转义

\n        \n        False  # 无法进行匹配
\\n       \n        True  # 需要在前面加\取消转义
\\\\n     \\n       True  # 在前面加双斜杠取消转义两个\
注意:在python中可以在字符串的前面加r取消转义,更加方便

七、贪婪匹配和非贪婪匹配

举例如下:

# 正则        # 待匹配的文本        		# 结果

<.*>         <script>alert(123)<script>    <script>alert(123)<script>
贪婪匹配:以最后一个大括号的出现作为结束标志
<.*?>        <script>alert(123)<script>    <script>  <script>
非贪婪匹配:以第一个大括号的出现为结束标志

注意:量词默认都是贪婪匹配,如果想修改为非贪婪匹配,只需要在量词后面加?即可

贪婪非贪婪通常都是利用左右两百年的条件作为筛选依据

八、re模块

在python中无法直接使用正则,需要借助模块(内置模块或第三方模块)

import re
1.findall
res = re.findall('a','jason oscar aaa ')  # 参数左边是正则表达式,右边是待匹配的文本,匹配所有结果组成列表
print(res)  # ['a', 'a', 'a', 'a', 'a']
2.search
res = re.search('a','jason oscar aaa ')
print(res)  # <_sre.SRE_Match object; span=(1, 2), match='a'>     找到一个就结束,没有则返回None
print(res.group())  # a  由于res的结果是一个看不懂的对象,因此需要使用group(),若没匹配到则无法调用group()且报错
3.finditer
res = re.finditer('a','jason oscar aaa ')
print(res)  # 结果是个迭代器对象,为了节省空间
print([i.group() for i in res])  # ['a', 'a', 'a', 'a', 'a']
4.compile
obj = re.compile('\d+')  # 提前写好后面方便重复使用
print(re.findall(obj,'sds15641sddsds'))
print(re.findall(obj,'4154sdfas5s115'))
print(re.findall(obj,'sd45ds45sdf55s'))

练习:

1、使用正则筛选出网站的数据
http://www.redbull.com.cn/about/branch
2、将公司名称 地址 邮编 电话筛选出来
3、展示可以是格式化输出也可以是文件存储

import re  # 调用正则
with open('data.txt', 'r', encoding='utf8') as f:
    file_data = f.read()  # 获取文件内容
res = re.findall("data-describe='.*?'><h2>(.*?)</h2><p class='mapIco'>(.*?)</p><p class='mailIco'>(\d{6})</p><p class='telIco'>(.*?)</p></li><li",file_data)  # 正则表达式
for i in res:  # 格式化输出
    print(f'''
    公司名称:{i[0]}
    公司地址:{i[1]}
    公司邮编:{i[2]}
    公司电话:{i[3]}
    ''')
posted @ 2022-03-28 21:38  马氵寿  阅读(95)  评论(0)    收藏  举报