7、Python中使用正则表达式
7.1 正则表达式语法(regular expression)
处理字符串时,常会用到查找符合某些复杂规则的字符串的需求。正则表达式就是用于描述这些规则的工具。正则表达式就是用于记录文本规则的代码。
7.1.1 行定位符
用来描述字符串的边界。^
表示行的开始;$
表示行的结尾。
7.1.2 元字符
\bmr\w*\b
:匹配以字母mr开头的单词,从单词开始处(\b),匹配字母mr,然后是任意数量的字母或数字(\w*),最后是单次结尾(\b)。
7.1.3 重复
匹配特定数量的字符: 例如匹配8位的QQ号:^\d{8}$
。
7.1.4 字符类
如果匹配没有预定义元字符的字符集合只需要子方括号里列出来它们就可以了。[aeiou]
就匹配任何一个英文元音字母。
7.1.5 排除字符
用于匹配不是指定字符的表达式用“^”:[^a-zA-Z]
:表示用于匹配一个不是子母的字符。
7.1.6 选择字符
包含条件选择的逻辑,需要选择字符(|)来实现。可以理解为“或”,例如匹配身份证:(^\d{15}$)|(^\d{18}$)|(^\d{17})|(\d|X|x)$
,表示可以匹配15位或者是18位,或者是17位数字和最后一位。最后一位可以是数字或者是X或者是x。
7.1.7 转义字符
正则表达式中的转义字符是(\),是将特殊字符(. ? \等等)变为普通字符。例如匹配IP地址时,127.0.0.1:[1-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}
。如果不加转义字符,.
可以匹配一个任意字符。
7.1.8 分组
小括号字符的第一个作用就是可以改变限定字符的作用范围。例如(thir|four)th
:表示匹配单词thirth或者是fourth。
小括号的第二个作用就是分组,即子表达式。例如:(\.[0-9]{1,3}){3}
就是对分组(\.[0-9]{1,3})
进行重复操作。
7.2 使用re模块实现正则表达式操作
引入模块 import re
7.2.1 匹配字符串
- 使用
match()
方法进行匹配。从字符串开始处进行匹配,起始位匹配成功,返回对象吧,否则返回None。
import re
pattern = r'mr_\w+' #模式字符串
string = 'MR_SHOP mr_shop' # 要匹配的字符串
match = re.match(pattern, string, re.I) # 匹配字符串不区分大小写
print(match) #匹配成功
string = '项目名称 MR_SHOP mr_shop'
match = re.match(pattern, string, re.I)
print(match) # 匹配失败
'''
<_sre.SRE_Match object; span=(0, 7), match='MR_SHOP'>
None
'''
print('匹配的起始位置:', match.start())
print('匹配的结束位置:', match.end())
print('匹配位置的元组:', match.span())
print('要匹配的字符串:', match.string)
print('匹配数据:', match.group())
'''
匹配的起始位置: 0
匹配的结束位置: 7
匹配位置的元组: (0, 7)
要匹配的字符串: MR_SHOP mr_shop
匹配数据: MR_SHOP
'''
定义一个验证手机号码的模式字符串,用该模式字符串验证两个手机号码,验证结果:
pattern = r'(13[4-9]\d{8})$|(15[01289]\d{8})'
mobile = '13634222222'
match = re.match(pattern, mobile)
if match == None:
print(mobile, '不是有效的电话号码')
else:
print(mobile, '是有效的电话号码')
# 13634222222 是有效的电话号码
- 使用
search()
方法进行匹配。search()
不仅可以在起始位置搜索,也可以在字符串的其他位置搜索。
pattern = r'mr_\w+'
string = 'MR_SHOP mr_shop'
match = re.search(pattern, string, re.I)
print(match) # <_sre.SRE_Match object; span=(0, 7), match='MR_SHOP'>
string = '项目名称MR_SHOP mr_shop'
match = re.search(pattern, string, re.I)
print(match) # <_sre.SRE_Match object; span=(4, 11), match='MR_SHOP'>
- 使用
findall()
方法。用于在整个字符串中搜索所有符合正则表达式的字符串并以列表的形式返回。
pattern = r'mr_\w+'
string = 'MR_SHOP mr_shop'
match = re.findall(pattern, string, re.I)
print(match) # ['MR_SHOP', 'mr_shop']
string = '项目名称MR_SHOP mr_shop'
match = re.findall(pattern, string)
print(match) # ['mr_shop']
如果在指定的模式字符串中包含分组,则返回与分组匹配的文本列表。
pattern = r'[1-9]{1,3}(\.[0-9]{1,3}){3}'
str1 = '127.0.0.1 192.168.1.66'
match = re.findall(pattern, str1)
print(match)
# ['.1', '.66']
上述代码并没有出现匹配的IP地址,因为模式字符串中出现了分组,得到的结果是根据分组进行匹配的结果,即(\.[0-9]{3}
匹配的结果。
pattern = r'([1-9]{1,3}(\.[0-9]{1,3}){3})'
str1 = '127.0.0.1 192.168.1.66'
match = re.findall(pattern, str1)
for it in match:
print(it[0])
'''
127.0.0.1
192.168.1.66
'''
7.2.2 替换字符串
使用sub()
方法实现字符串的替换。
pattern = r'1[34578]\d{9}'
string = '中奖号码是:84978981 联系电话是:13632453167'
reslut = re.sub(pattern, '1XXXXXXXXXXX', string)
print(reslut) # 中奖号码是:84978981 联系电话是:1XXXXXXXXXXX
pattern = r'(黑客)|(抓包)|(监听)|(*)'
about = '我是一名程序员,我喜欢看黑客方面的图书,想研究一下*。'
sub = re.sub(pattern, '@_@', about)
print(sub)
about = '我是一名程序员,我喜欢看计算机网络方面的图书,喜欢开发网站。'
sub = re.sub(pattern, '@_@', about)
print(sub)
'''
我是一名程序员,我喜欢看@_@方面的图书,想研究一下@_@。
我是一名程序员,我喜欢看计算机网络方面的图书,喜欢开发网站。
'''
7.2.3 使用正则表达式分割字符串
pattern = r'[?|&]'
url = 'https://www.mingrisoft.com/login.jsp?username="mr"&pwd="mrsoft"'
reslut = re.split(pattern, url)
print(reslut)
# ['https://www.mingrisoft.com/login.jsp', 'username="mr"', 'pwd="mrsoft"']
str1 = '@明日科技 @扎克伯格 @盖茨'
pattern = r'\s*@'
list1 = re.split(pattern, str1) #用空格和@或单独的@分割字符串
print('您@的好友有:')
for it in list1:
if it != "": # 输出不为空的元素
print(it) # 输出每个好友名
'''
您@的好友有:
明日科技
扎克伯格
盖茨
'''