正则表达式是一种用于匹配字符串的表达式,它描述了字符串的数量和顺序,可以用于搜索、替换和验证文本数据。使用正则表达式可以方便地在大量文本中查找、匹配和提取特定的模式,它在计算机编程语言和文本编辑器中广泛应用。
1.是一个对象,叫正则对象
2.是一个强大的字符串匹配和处理工具(除了处理字符串,其他的什么都做不了)
3.它是火星文,一般人很难理解(程序界的摩斯码)
4.它还是一种思维方式
5.容易学,但是也非常容易忘记
某东手机号注册效验
要求:手机号必须是11位、手机号必须以13 15 17 18 19开头、必须是纯数字
1.普通代码实现
while True:
# 1.获取用户输入的手机号
phone_num = input('请输入您的手机号>>>>:').strip()
# 2.判断是不是11位
if phone_num == 11:
#.3.判断是不是纯数字
if phone_num.isdigit():
# 4.判断手机号的开头
if phone_num.startswith('13')or phone_num.startswith('15')or phone_num.startswith('17') or phone_num.startswith('18') or phone_num.startswith('18')
print('手机号码输入正确')
else:
print('手机号开头不符合')
else:
print('号码不是纯数字')
else:
print('手机号必须是11位')
2.正则表达式实现
import re
phone_num = input('请输入您的手机号>>>>:').strip()
if re.match('^(13|14|15|18)[0-9]{9}$', phone_num):
print('是合法的手机号码')
else:
print('不是合法的手机号码')
字符组默认匹配方式是挨个挨个匹配
[0123456789] 匹配0到9任意一个数(全写)
[0-9] 匹配0到9任意一个数(缩写)
[a-z] 匹配26个小写英文字母
[A-Z] 匹配26个大写英文字母
[0-9a-zA-Z] 匹配数字或者小写字母或者大写字母,用来验证十六进制字符
ps:字符组内所有的数据默认都是或的关系
eg: 以[0-9]为例,我们尝试用几个待匹配字符串得到匹配结果
待匹配字符串 匹配结果 解释
'5' ['5'] [0-9]中有5,所以可以匹配到5
'o' ['None'] 字母不符合条件
'79i1' ['7','9','1'] 每个匹配到的结果 ,都会从字符串中切出
'11111' ['1','1','1','1','1'] 有几个1取几个1
元字符 | 匹配内容 |
---|---|
. | 匹配除换行符以外的所有字符 |
\w | 匹配字母或数字或下划线 |
\s | 匹配任意的空白符 |
\d | 匹配数字 |
\t | 匹配一个制表符 |
\b | 匹配一个单词结尾 |
^ | 匹配一个字符串的开始 |
s | 匹配一个字符结尾开始 |
\W | 匹配非字母或数字或下划线 |
\D | 匹配非数字 |
\S | 匹配非空白符 |
aIb | 匹配字母a或者字母b |
() | 匹配括号内的表达式,也表示一个组 |
[…] | 匹配字符组中的字符 |
[^…] | 匹配除了字符组中的所有字符 |
量词 | 用法说明 |
---|---|
* | 重复零次或更多次 |
+ | 重复一次或更多次 |
? | 重复一次或零次 |
{n} | 重复n次 |
{n,} | 重复n次或更多次 |
{n,m} | 重复n到m次 |
正则表达式默认为贪婪匹配,也就是尽可能多的向后匹配字符,比如 {n,m} 表示匹配前面的内容出现 n 到 m 次(n 小于 m),在贪婪模式下,首先以匹配 m 次为目标,而在非贪婪模式是尽可能少的向后匹配内容,也就是说匹配 n 次即可。
1.贪婪匹配:在满足匹配时,匹配尽可能长的字符串,默认情况下,采用贪婪匹配
2.加上? 会将贪婪匹配模式转为非贪婪匹配模式,会匹配尽量短的字符串
贪婪模式转换为非贪婪模式的方法很简单,在元字符后添加“?”即可实现,如下所示:
量词 | 用法说明 |
---|---|
.* | .*? |
+ | +? |
? | ?? |
{n,m} | {n,m}? |
在python中,无论是正则表达式,还是待匹配的内容,都是以字符串的形式出现的,在字符串中\也有特殊的含义,本身还需要转义。所以如果匹配一次"\n",字符串中要写成’\n’,那么正则里就要写成"\\n",这样就太麻烦了。这个时候我们就用到了r’\n’这个概念,此时的正则是r’\n’就可以了。
正则 | 待匹配字符 | 匹配结果 | 说明 |
---|---|---|---|
\n | \n | False | 因为在正则表达式中\是有特殊意义的字符,所以要匹配\n本身,用表达式\n无法匹配 |
\n | \n | True | 转义\之后变成\,即可匹配 |
‘\\n’ | ‘\n’ | True | 如果在python中,字符串中的’‘也需要转义,所以每一个字符串’'又需要转义一次 |
r’\n’ | r’\n’ | True | 在字符串之前加r,让整个字符串不转义 |
在Python中如果要使用正则,则需要使用到re(regluar express)模块
import re
ret = re.findall('a', 'eva egon yuan') # 返回所有满足匹配条件的结果,放在列表里
print(ret) #结果 : ['a', 'a']
ret = re.search('a', 'eva egon yuan').group()
print(ret) #结果 : 'a'
# 函数会在字符串内查找模式匹配,只到找到第一个匹配然后返回一个包含匹配信息的对象,该对象可以
# 通过调用group()方法得到匹配的字符串,如果字符串没有匹配,则返回None。
ret = re.match('a', 'abc').group() # 同search,不过尽在字符串开始处进行匹配
print(ret)
#结果 : 'a'
ret = re.split('[ab]', 'abcd') # 先按'a'分割得到''和'bcd',在对''和'bcd'分别按'b'分割
print(ret) # ['', '', 'cd']
ret = re.sub('\d', 'H', 'eva3egon4yuan4', 1)#将数字替换成'H',参数1表示只替换1个
print(ret) #evaHegon4yuan4
ret = re.subn('\d', 'H', 'eva3egon4yuan4')#将数字替换成'H',返回元组(替换的结果,替换了多少次)
print(ret)
obj = re.compile('\d{3}') #将正则表达式编译成为一个 正则表达式对象,规则要匹配的是3个数字
ret = obj.search('abc123eeee') #正则表达式对象调用search,参数为待匹配的字符串
print(ret.group()) #结果 : 123
import re
ret = re.finditer('\d', 'ds3sy4784a') #finditer返回一个存放匹配结果的迭代器
print(ret) #
print(next(ret).group()) #查看第一个结果
print(next(ret).group()) #查看第二个结果
print([i.group() for i in ret]) #查看剩余的左右结果
使用小括号括起来的正则表达式就是无名分组
res = re.search('^[1-9](\d{14})(\d{2}[0-9x])?$','110105199812067023')
print(res)
print(res.group()) # 110105199812067023
print(res.group(1)) # 10105199812067
print(res.group(2)) # 023
# findall针对分组优先展示 无名分组
"""
如果是findall,分组优先展示,无名分组
"""
res = re.findall("^[1-9](\d{14})\d{2}[0-9x]?$",'110105199812067023')
print(res) # ['023']
使用小括号括起来的正则表达式然后起个名字就是有名的
res = re.search('www.(?Pbaidu|oldboy)(?P.com)' ,'www.oldboy.com')
print(res.group()) # www.oldboy.com
print(res.group('name')) # oldboy
print(res.group(0)) # www.oldboy.com
print(res.group(1)) # oldboy
print(res.group(2)) # .com
print(res.group('haha')) # .com
爬取红牛分公司官网数据
with open('a.txt', 'r', encoding='utf-8') as f:
data = f.read()
import re
title_list = re.findall('(.*?)
', data)
address_list = re.findall("(.*?)
", data)
email_list = re.findall("(.*?)
", data)
phone_list = re.findall("(.*?)
", data)
res_list = zip(title_list, address_list, email_list, phone_list)
# print(list(res_list))
for i in list(res_list):
print("""
公司名称:%s,
公司地址:%s,
公司邮编:%s,
公司电话:%s,
""" % (i[0], i[1], i[2], i[3]))