import re 正则表达式相关
进行验证匹配
pattern = re.compile('正则表达式')
:规定一个正则表达式
match_obj = pattern.match('匹配对象')
:利用正则表达式在目标中进行匹配,返回match_obj
match_obj:<re.Match object; span=(位置), match=‘目标字符串’>
import re
ss = '邮箱地址是:xxxx@XXXX.com' # 需要匹配的文本
pattern1 = re.compile(r'[\u4e00-\u9fa5]+') # 正则规则,返回pattern对象
match_obj1 = pattern1.match(ss) # 利用pattern进行匹配,获取结果,返回match_obj匹配对象
aim1 = match_obj1.group() # 获取匹配的内容部分
aim2 = match_obj1.span() # 获取内容的位置
print(aim1)
====================================
邮箱地址是 (0, 5)
re.match('规则','原串',re.I)
:当原串开头存在目标时,返回match_obj(忽略大小写)
re.fullmatch('规则','原串',re.I)
:当原串与目标完全匹配时,返回match_obj(忽略大小写)
re.search('规则','原串',re.I)
:当原串中存在目标时,返回match_obj(忽略大小写),位置是第一个目标的位置
re.findall('规则','原串',re.I)
:查找出原串中所有匹配的字符串,返回一个列表。
re.sub('规则','目标',原串)
:按规则搜索并用目标替换原串中所有符合规则的位置,目标可以是一个函数
常用符号与量词
.
:匹配任意一个字符
[]
:匹配一个在此区间内的字符
{n}
:匹配区间内的n位字符
{n,}
:匹配区间内的n位字符及以上
{,n}
:匹配区间内的n位字符及以下
{x,y}
:匹配区间内的x位字符及以上,y位字符及以下
*
:匹配0到多个字符
+
:匹配1到多个字符
?
:匹配0到1个字符
^
:从字符串开头开始匹配
$
:从字符串结尾开始匹配
^[1-9][a-z,A-Z]*[0-9]
{2}:以1-9开头,以两位数字结尾,中间仅包含0到多个大小写字母的字符串
^[1-9]\d{5,9}$
:以1-9开头,长度在6-10位之间,以数字结尾的字符串(多用于判断原串是否合乎标准)
分组与命名操作
|
:表示或的关系
()
:表示分组的关系,一个pattern里可以有多个组
(\number)
:表示分组的引用关系,匹配内容和第number个组一致
(?P<name>规则)
:利用此格式给分组规则命名,之后可以利用名字来进行引用
# 分组匹配指定的短语
import re
ss = 'hi Mike!hi Kitty!'
m_obj = re.findall(r'(hi|hello) (Tom|Mike|Kitty)',ss,re.I) # 第一组匹配问候,第二组匹配人名
print(m_obj)
====================================
[('hi', 'Mike'), ('hi', 'Kitty')]
# 获取分组后指定组匹配的内容
import re
ss = 'hi Mike!hi Kitty!'
s_ptn = r'(hi|hello) (Tom|Mike|Kitty)' # 第一组匹配问候,第二组匹配人名
m_obj1 = re.findall(s_ptn,ss,re.I)
for i in m_obj1:
print(i[1],end='\t')
print()
m_obj2 = re.search(s_ptn,ss,re.I)
print(m_obj2.group(1))
print(m_obj2.group(2))
====================================
Mike Kitty
hi
Mike
# 判断三层嵌套标签是否正确配对
import re
ss = '<div><ul><li></li></ul></div>'
s_ptn1 = r'<(.+)><(.+)><(.+)></\3></\2></\1>' # 利用编号
# 利用命名
s_ptn2 = r'<(?P<out>.+)><(?P<mid>.+)><(?P<inn>.+)></(?P=inn)></(?P=mid)></(?P=out)>'
m_obj1 = re.findall(s_ptn1,ss,re.I)
m_obj2 = re.findall(s_ptn2,ss,re.I)
print(m_obj1)
print(m_obj2)
贪婪与非贪婪
当你使用 +
*
等通配符时,默认的匹配模式为 贪婪模式
,即尽可能多的进行匹配,例如:
规则:ab+;字符串:abbbbbbbbbbbbbc
匹配结果:abbbbbbbbbbbbb
但是有的时候我们不希望它匹配所有,就需要用到非贪婪模式 +?
*?
进行匹配,例如:
规则:ab+?;字符串:abbbbbbbbbbbbbc
匹配结果:ab
import re
ss = '<div>hello</div><div>world</div>'
ptn1 = r'<(?P<lbl>.+)>.+</(?P=lbl)>'
ptn2 = r'<(?P<lbl>.+)>.+?</(?P=lbl)>'
m_obj1 = re.match(ptn1,ss)
m_obj2 = re.match(ptn2,ss)
print(m_obj1.group())
print(m_obj2.group())
====================================
<div>hello</div><div>world</div>
<div>hello</div>
预定义字符
\d
:等同于 [0-9]
,匹配数字
\D
:等同于 [^0-9]
,匹配非数字
\w
:等同于 [a-zA-Z0-9_]
,匹配大小写字母,数字和下划线
\W
:等同于 [^a-zA-Z0-9_]
,匹配非大小写字母,数字或下划线
\s
:等同于 [ \t\n\r\f\v]
,匹配空白字符。空格/水平制表符/换行/回车/换页/垂直制表符
\S
:等同于 [^ \t\n\r\f\v]
,匹配非空白字符
\b
:匹配仅在单词的开头或结尾出现的空字符串
\B
:匹配空字符串,但不匹配单词的开头或结尾出现的。
建议在写正则规则时,通过在规则字符串开头添加
r
,来避免转义字符和预定义字符之间的混淆例如:
r'\b[a-zA-Z]+\b'
,\b
在预定义字符与转义字符中均有定义,利用r
来避免转义
几类应用
判断用户名合法性
import re
username = input('UserName:')
pat_name = re.compile(r'^[a-z_]\w{6,}$') # 用户名规则
m_name = pat_name.search(username) # 利用规则进行匹配,获取结果
if m_name:
print('UserName is legal ')
else:
print('UserName is illegal')
判断国内手机号合法性
import re
phoneno = input('PhoneNo:')
pat_phone = re.compile(r'^1[3578]\d{9}$') # 国内手机号规则
m_phone = pat_phone.search(phoneno) # 利用规则进行匹配,获取结果
if m_phone:
print('PhoneNo is legal ')
else:
print('PhoneNo is illegal')
获取一个句子中的所有单词
import re
ss = 'Hello Python World '
pat_ss = re.compile(r'\b[a-zA-Z]+\b') # 单词规则
m_ss = pat_ss.findall(ss) # 利用规则进行匹配,获取结果
print(m_ss)
=============================
['Hello', 'Python', 'World']
去除句子中多余的空格
import re
ss = ' Hello Python World '
ss = re.sub(r'\s+',' ',ss) # 利用正则清除串中多余空格
ss = ss.strip() # 利用strip去除两端多余空格
print(ss)
=============================
Hello Python World
利用函数处理需替换的字符串
import re
ss = 'num1:52.74,num2:189.67:num3:67.85,num4:67.4'
def fround(mobj): # 四舍五入
num = float(mobj.group())
num = round(num)
return str(num) # 必须返回一个str类型
ss = re.sub(r'\d+[.]*\d*',fround,ss)
print(ss)
=============================
num1:53,num2:190:num3:68,num4:67