正则表达式与re模块

85 阅读4分钟

正则表达式简介

'''正则不属于任何一门编程语言,是一门独立的学科,主要用于数据的查找与筛选'''
正则前戏:
	需求:编写校验手机号是否合法,使用python代码实现。
1.方式1:使用if嵌套
phone_num = input('请输入您的手机号').strip()
if phone_num.isdigit():
    if len(phone_num) == 11:
        if phone_num.startswith('13') or phone_num.startswith('15') or phone_num.startswith('18'):
            print(phone_num)
        else:
            print('输入不合法')
    else:
        print('手机号必须是十一位')
else:
    print('请输入纯数字')
2.方式2:re模块用正则表达式  
import re
phone_num = input('请输入您的手机号').strip()
if re.match('^[13|15|18][0-9]{9}', phone_num):
    print(phone_num)
else:
    print('输入不合法')
总结:
	正则本质上就是使用一些符号的组合产生一些特殊的含义,然后再去字符串中筛选符合条件的数据。

正则表达式之字符组

正则表达式线上测试网址:http://tool.chinaz.com/regex/
'''字符组(在没有量词修饰)一次只会针对一个数据值'''
[0-9]		匹配[0-9]之间的任意一个数字
[A-Z]		匹配[A-Z]之间的任意一个字母
[a-z]		匹配[a-z]之间的任意一个字母
在中括号中编写的多个数据值彼此都是 或 的关系
[0-9a-zA-Z] 表示数字小写大写字母都能匹配

正则表达式之特殊符号

'''特殊符号(在没有量词修饰)一次只会针对一个数据值'''
符号作用
.匹配除换行符之外的任意字符
\w(小写w)匹配字母或数字或下划线
\W(大写W)匹配非字母或下划线
\d匹配数字
匹配字符串的开头
$匹配字符串的结尾
^a$明确限制想要查找的数据值(a)
a|b匹配字符a或b
()给正则表达式分组,不影响正则的匹配,用于后续给正则起别名
[]匹配字符组中的字符
[^]匹配除了字符组中的其他字符 (取反)

正则表达式之量词

'''在正则表达式中所有的量词都是默认贪婪匹配(尽可能多的匹配)'''
量词不能单独使用,必须跟在表达式的后面,修饰紧挨着的左边的那一个值
量词符号作业
*重复零次或更多次(默认尽可能多)
+重复一次或更多次(默认尽可能多)
重复0次或1次(默认一次)
{n}重复n次
{n,}重复n次或更多次
{n,m}重复n到m次

贪婪匹配与非贪婪匹配

待匹配的文本:<script>alert(123)</script>
1.贪婪匹配:<.*> # 尽可能多
结果:<script>alert(123)</script>
2.非贪婪匹配:<.*?> # 尽可能少
结果:<script>  </script>
'''
所有量词默认都是贪婪匹配,但在量词后面加一个?就会变成非贪婪匹配
贪婪匹配一般用 .* 表示 
非贪婪匹配一般用 .*? 表示
开始和结束的标志由上述符号两边的表达式决定
'''

取消转义

正则表达式中取消斜杠与字母的特殊含义的方法:在\前面加\
\n   ---->    \\n
\\n    ---->    \\\\n
在python中有更加便捷的写法
r'\n'
r'\\n'

re模块常用方法

import re
1.findall
res = re.findall('aa', 'aabbcc aabbcc aaa')
print(res)  # ['aa', 'aa', 'aa']
# findall 可以通过正则表达式筛选出文本中符合条件的数据,并以列表返回
2.finditer
res = re.finditer('aa', 'aabbcc aabbcc aaa')
print(res)  # <callable_iterator object at 0x00000183AE8536A0>
print(res.__next__())  # <re.Match object; span=(0, 2), match='aa'>
# finditer与findall作用一致,只不过结果会返回成迭代器对象,节省内存。调用__next__()后还会返回该元素在原文本中的位置坐标
3.search
res = re.search('aa', 'aabbcc aabbcc aaa')
print(res)  # <re.Match object; span=(0, 2), match='aa'>
# 通过正则匹配到一个符合条件的数据就结束(非贪婪匹配)
4.match
res = re.match('aa', '1aabbcc aabbcc aaa')
print(res)  # None
# 通过正则从字符串开头进行匹配,一旦开头不符合,直接返回None(^匹配)
6.compile
obj = re.compile('aa')
print(re.findall(obj, 'ahduqhube1h2qqaa'))  # ['aa']
print(re.findall(obj, 'dhqiuahiuaaaihaaa'))  # ['aa', 'aa']
print(re.findall(obj, '111nqaaaaqq1'))  # ['aa', 'aa']
# 提前定义好正则,之后可以反复使用,减少代码冗余

re模块其他操作

1.分组
res = re.findall('ab(c)', 'abcabcabcabc')
print(res)  # ['c', 'c', 'c', 'c']
# findall会优先展示分组后的正则匹配到的结果

res = re.findall('ab(?:c)', 'abcabcabcabc')
print(res)  # ['abc', 'abc', 'abc', 'abc']
# findall 也可以通过在括号内的最前面加 ?: 的形式取消分组优先展示

res = re.search('ab(c)', 'abcabcabcabc')
print(res)  # <re.Match object; span=(0, 3), match='abc'>
# search 并不会优先展示分组后正则匹配到的结果
print(res.group())  # abc
print(res.group(0))  # abc
print(res.group(1))  # c

2.别名
res = re.search('a(?P<id>b)(?P<name>c)', 'abcabcabcabc')
print(res.group())  # abc
print(res.group(1))  # b
print(res.group('id'))  # b
print(res.group('name'))  # c
# 我们在分组时可以在括号内部的最前面加 ?P<别名> 的方式来为分组起别名