思维导图笔记
在使用re模块时,首先要先用import语句将其引入,具体代码如下:
import re一、匹配字符串
匹配字符串可以使用re模块提供的match()、search()和findall()等方法。
1.使用match()方法进行匹配match()方法用于从字符串的开始处进行匹配,如果在起始位置匹配成功,则返回Match对象,否则返回None。其语法格式如下:
re.match(pattern,string,[flags])
参数说明如下:
pattern:表示模式字符串,由要匹配的正则表达式转换而来。
string:表示要匹配的字符串。
flags:可选参数,表示标志位,用于控制匹配方式,如是否区分字母大小写。常用的标志即其说明如下表:
| 标志 | 说明 |
|---|---|
| A或ASCII | 对于w、W、b、B、d、D、s和S只进行ASCII匹配(适用于python 3.x) |
| I或IGNORECASE | 执行不区分字母大小写的匹配 |
| M或MULTILINE | 将^和$用于包括整个字符串的开始和结尾的每一行(默认情况下,仅适用于整个字符串的开始和结尾处) |
| S或DOTALL | 使用“.”字符匹配所有字符,包括换行符 |
| X或VERBOSE | 忽略模式字符串中未转义的空格和注释 |
例如,匹配字符串是否以“mr_”开头的,其中不区分字母大小写,代码如下:
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)
疑惑:
01.pattern中为什么不能用r'^mr_'或者r'bmr_'这两个不都是匹配字符串的开头的'mr_'吗?
02.string中两个能匹配的值放到了一个引号之中,用空格分割开,就都能匹配到了吗?
执行结果如下:
None
通过上面的例子可以看出,第二次输出的结果是None,因为第二个开头是'项目名称 MR_....'不是以'mr_'开头的,这是因为match()方法是从字符串的开始位置处进行匹配,当第一的字母不符合条件时,就不再进行匹配,直接返回None。
Match对象中包含了匹配值的位置和匹配数据。其中,要获取匹配值的起始位置可以使用Match()对象的start()方法;要获取匹配值的结束位置可以使用end()方法;通过span()方法可以返回匹配位置的元组;通过string属性可以获取要匹配的字符串。例如,下列代码:
import re
pattern=r'mr_w+' #模式字符串
string='MR_SHOP mr_shop' #要匹配的字符串
match=re.match(pattern,string,re.I) #匹配字符串,不区分大小写
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
疑惑:
01.match()方法匹配的结果只匹配第一个符合条件的值,而且值与值之间用空格分开?
例子:验证输入的手机号码是否有效。
print('判定是否是中国移动的手机号')
import re
pattern=r'(13[4-9]d{8})$|(15[01289]d{8})$'
mobile=input('请输入要判定的手机号码:')
outcome=re.match(pattern,mobile)
if outcome==None:
print('您输入的手机号不是中国移动的手机号')
else:
print('您输入的手机号是中国移动的手机号')
#因为match是从头开始匹配的所以可以不加^在开头,但是结尾处要加$不然它会匹配到前面符合但是后面不符合的数值
2.使用search()方法进行匹配
search()方法用于在整个字符串中搜索第一个匹配的值,如果在起始位置匹配成功,则返回Match对象,否则返回None。其语法格式如下:
re.search(pattern,string,[flags])
参数说明同match()方法相同
import re pattern=r'mr_w+' #模式字符串 string='MR_SHOP mr_shop' #要匹配的字符串 match=re.search(pattern,string,re.I) #匹配字符串,不区分大小写 print(match) #输出匹配结果 string='项目名称 MR_SHOP mr_shop' match=re.search(pattern,string,re.I) print(match)
执行结果如下:
从上述运行结果中可以看出,search()方法不仅仅是在字符串的起始位置处搜索,还可以在其他位置处搜索有符合的匹配。
例子:验证是否出现危险字符。
print('检验句子是否出现敏感词')
while True:
import re
pattern=r'黑客|监听|窃取|色色'
about=input('检验句子:')
a=re.search(pattern,about) #进行模式匹配
print(a)
if a==None: #判断是否为None,为真表示匹配失败
print('该句子未出现敏感词')
else:
print('该句子出现了敏感词')
疑问:
01.书本例题中pattern后的每个词汇都加了(),但我自己做的时候没加,我感觉只和分组有关系,不知道会不会有其他的影响。
3.使用findall()方法进行匹配findall()方法用于在整个字符串中搜索所有符合正则表达式的字符串,并以列表的形式返回。如果匹配成功,则返回包含匹配结构的列表,否则返回空列表。其语法格式如下:
re.findall(pattern,string,[flags])
参数说明同match()方法。
例如,搜索以“mr_”开头的字符串,代码如下:
import re pattern=r'mr_w+' #模式字符串 string='MR_SHOP mr_shop' #要匹配的字符串 match=re.findall(pattern,string,re.I) #匹配字符串,不区分大小写 print(match) #输出匹配结果 string='项目名称 MR_SHOP mr_shop' match=re.findall(pattern,string) #区分大小写 print(match)
执行上述代码,输出结果如下:
['MR_SHOP', 'mr_shop'] ['mr_shop']
如果在指定的模式字符串中包含返祖,则返回与分组匹配的文本列表。例如,下列代码:
import re
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']
疑问:
01.127.0.0.1和192.168.1.66中.0、.168都符合(.[0-9]{1,3})的条件为什么只出现.1和.66?
从上述结果可以看出,并没有得到匹配的IP地址,这是因为模式字符串中出现了分组,所以得到的结果是根据分组进行匹配的结果,即(.[0-9]{1,3})的结果。如果想获取整个模式字符串的匹配,可以将整个模式字符串使用一堆小括号进行分组,然后在获取结果时,只取返回值列表的第一个元素(是一个元组)的第一个元素,代码如下:
import re
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 item in match:
print(item[0])
执行结果如下:
127.0.0.1 192.168.1.66
上例中要输入item[0]会出现上面的执行结果,若输入item不加[0],会出现如下结果:
('127.0.0.1', '.1')
('192.168.1.66', '.66')
每个元组中都取其第一个,列出
二、替换字符串sub()方法用于实现字符串的替换。其语法格式如下:
re.sub(pattern,repl,string,count,flags)
参数说明如下:
pattern:表示模式字符串,有要匹配的正则表达式转换而来。
repl:表示替换的字符串。
string:表示要被查找替换的原始字符串。
count:可选参数,表示模式匹配后替换的最大次数,默认值为0,表示替换所有的匹配。
flags:可选参数,具体看match()方法
例子:隐藏中奖信息中的手机号码
import re
pattern=r'1[345678]d{9}' #第二位只能是[]里面的,剩下的位数啥数字都行
repl='1**********' #pattern被完整替换成repl
string='中奖号码为:18835345645 请联系:15685
result=re.sub(pattern,repl,string)
print(result)
输出结果如下:
中奖号码为:1********** 请联系:15685
例子:替换出现的危险字符
import re
danger=r'色色|黑客|抓包|监听'
string=input('请输入语句:')
repl='**'
result=re.sub(danger,repl,string)
print(result)
三、使用正则表达式分割字符串
split()方法用于实现根据正则表达式分割字符串,并以列表的形式返回。与字符串对象的split()方法不同的是分隔字符由模式字符串指定,而且只能同时进行一种字符分割。
re.split(pattern,string,[maxsplit],[flags])
参数说明如下:
maxsplit:可选参数,表示最大的拆分次数。
例子:从给定的url地址中提取出请求地址和各个参数
import re url='https://www.bilibili.com/video/BV1gV411i7vq?from=search&seid=7848448755056524409&spm_id_from=333.337.0.0' pattern=r'[?|&]' result=re.split(pattern,url) print(result)
执行结果如下
['https://www.bilibili.com/video/BV1gV411i7vq', 'from=search', 'seid=7848448755056524409', 'spm_id_from=333.337.0.0']
例子:输出被@的好友名称
import re
name='@亚斯娜 @北白川玉子 @小鸟游六花 @小鸟游十花'
pattern=r'@'
result=re.split(pattern,name)
print('您@的好友有:')
for item in result:
print(item)
#标准
import re
name='@亚斯娜 @北白川玉子 @小鸟游六花 @小鸟游十花'
pattern=r's*@' #这里多用了s*,我没用不知道会不会有别的影响
result=re.split(pattern,name) #这里分割之后开头会多出个空白的字符串
print('您@的好友有:')
for item in result:
if item!='': #这里进行把列表里的空白单位给删除
print(item)
疑问:
01.用re.split()分割了之后为什么会多出一个空白字符串?
02.这里多用了s*,我没用不知道会不会有别的影响?



