小马哥正在为Python的所有常见知识进行汇总,更会有大量实战项目
点击--> 全栈工程师养成---Python内容导航页 <--查看所有Python内容
导语
正则表达式本质是一种字符串模式或者叫字符串模板,用来匹配一些列的字符串,找到目标字符串的过程就是匹配或者搜索,找到这些目标字符串之后,就可以对其进行提取,进行拆分,进行替换等等. 这也就是正则表达式和编程语言的逻辑关系,正则表达式规定了如何定义模式,编程语言使用正则表达式确定的逻辑模式,进行功能实现(匹配,搜索,提取,查分,替换等功能).
主要内容:
- (2)先使用Python的re模块,实现正则表达式编程
- (1)正则表达式基本知识点
我故意把顺序倒过来,虽然先有正则再有Python对正则表达式的支持, 我们先把知识用起来,然后不用太多解释,你已经清楚正则是用来干什么了.目的还是保证: 一篇文章精通正则表达式,以及Python使用正则表达式熟练编程.
(一)用Python针对正则表达式编程
先把"见猪跑",直观认识正则表达式与Python利用正则表达式实现一定功能,介绍常用的函数或者方法
1.1 match()函数
作用: 匹配正则表达式,如果匹配成功就返回一个匹配对象;如果匹配失败,就返回None. 匹配对象的group()方法用于显示成功的匹配.
例1,实现最简单的正则表达式,
import re
# 正则表达式模式
pattern = 'China'
# 字符串文本
data = 'China'
# 通过re模块的的match方法,从data的起始部分开始,对正则表达式模式进行比对,如果匹配,返回一个匹配对象;否则返回None
result = re.match(pattern,data)
print(type(result)) # 返回 <class 're.Match'>
print(result.group()) # Match对象的group()会返回成功的匹配.
例2,最简单的正则表达式模式,之如果匹配失败是什么样子的
import re
pattern = 'China'
datas= 'Chinese','Python','China is a great country'
for data in datas:
result = re.match(pattern,data)
if result is not None:
print("匹配成功: ",result)
else:
print('匹配失败: ',data)
匹配失败: Chinese
匹配失败: Python
匹配成功: <re.Match object; span=(0, 5), match='China'>
上面的模式(或者认为是模板)中,pattern就是一个简单的字符串,但是这样的模式只能匹配一个单词,如果想匹配更多的情况,模式应该怎么写?
例3,能够匹配一个范围的字符
import re
pattern = '[abc]' #使用[]括起来的内容,代表一个集合,代表匹配集合内的任意一个字符,[abc]代表可以匹配a或者b或者c
datas = 'a','b','c','e','xay'
for data in datas:
result = re.match(pattern,data)
if result is not None:
print('Match Successfully: ',result.group()) # group()函数的作用: 返回Match对象匹配到的字符内容
else:
print('Match Failed: ',data)
例4,上面的例子中[abc]指代了一个集合,元素之间是或的关系,也可以把这个集合看做一个范围,
还有一种表示方法[a-z][A-Z][0-9],也是指代范围,[a-c]也是同样的意思
import re
pattern = '[a-e]' #[a-e]代表了a到e这个字符范围内的任何一个字符
datas = 'a','b','c','e','xay'
for data in datas:
result = re.match(pattern,data)
if result is not None:
print('Match Successfully: ',result.group()) # group()函数的作用: 返回Match对象匹配到的字符内容
else:
print('Match Failed: ',data)
例5,点号'.' 匹配任意的单个字符(换行符和非字符除外)
import re
pattern = '李.'
names='李逵','李鬼','小李'
for name in names:
isMatched = re.match(pattern,name)
if isMatched:
print('Match Successfully: ',isMatched)
else:
print('Match Faied: ',name)
Match Successfully: <re.Match object; span=(0, 2), match='李逵'>
Match Successfully: <re.Match object; span=(0, 2), match='李鬼'>
Match Faied: 小李
1.2 search()函数
作用: 在字符串中查找指定的模式,返回第一次出现的位置
match()函数的作用是在目标字符串的起始位置开始匹配,是否符合正则表达式模式. 我们很多场景可能不一定在字符串起始位置,更多情况是在字符内搜索是否有匹配正则模式的字符串存在,这就是search()函数的存在意义了.
例1,在一段文本中查找目标字符串
import re
data = '我爱伟大的祖国,I love China,China is a great country' #China在data字符串中的位置区间为[15,20) 半开半闭区间
pattern = 'China'
result = re.search(pattern,data)
print(result.group())
print(data[19])
China
a
例2,点号"."的使用,搜索除去换行符之外的任意字符
import re
sentence='华为是华人的骄傲' #1,通过这个句子1可以体会点号的作用;2,search()函数会返回第一次匹配
pattern='华.'
result = re.search(pattern,sentence)
if result:
print(result.group())
华为
who laughs last laughs best
1.3 findall()和finditer()函数
作用:
- findall()查询字符串中某个正则表达式全部的非重复出现情况,返回的是一个列表.
- finditer()返回的是一个迭代器,所以相比findall()更加节省内存
import re
sentence='华为是华人的骄傲'
pattern = '华.'
result = re.findall(pattern,sentence)
print(result)
['华为', '华人']
import re
sentence = '华为是华人的骄傲'
pattern = '华.'
result = re.finditer(pattern,sentence)
print(type(result))
<class 'callable_iterator'>
1.4 group()和groups()方法
作用: 匹配对象的两个方法
-
匹配对象: match()或者search()成功调用后返回的对象
-
子组: 圆括号对匹配模式的各个部分进行分组和提取操作,子组可以带来的方便是,不用通过match之后,再来对特定字符串进行抽取
-
group(): 返回整个匹配对象或者返回特定的子组
-
groups(): 返回一个包含唯一或者全部子组的元组
-
如果没有子组的要求,那么当group()仍然返回整个匹配时,groups()返回一个空元组.
例1,无子组的模式返回使用group()匹配对象
import re
pattern = 'a'
data = 'abcd'
result = re.match(pattern,data)
print(result)
print(result.group())
print(result.groups())
<re.Match object; span=(0, 1), match='a'>
a
()
import re
pattern = '(华.)\w(华.)'
sentence = '华为是华人的骄傲'
result = re.search(pattern,sentence)
print(result)
print(result.group()) #返回整个匹配对象
print(result.group(0)) #返回整个匹配对象
print(result.group(1)) #返回子组1
print(result.group(2)) #返回子组2
print(result.groups()) #返回包含所有子组的元组
<re.Match object; span=(0, 5), match='华为是华人'>
华为是华人
华为是华人
华为
华人
('华为', '华人')
1.5 compile()函数
作用: 编译正则表达式
import re
pattern = '(华.)\w(华.)'
sentence = '华为是华人的骄傲'
compiled_pattern = re.compile(pattern) #<class 're.Pattern'>
print(type(compiled_pattern))
# result = re.match(compiled_pattern,sentence) #(-1-)这样做,
result = re.match(pattern,sentence) # (-2-)<class 're.Match'>
print(result)#(-1-)(-2-)得到的结果都是一样的,但是在多次用到compiled_pattern的时候,会节省了编译pattern的这个过程
<class 're.Pattern'>
<re.Match object; span=(0, 5), match='华为是华人'>
1.6 sub()和subn()函数
作用: 实现搜索和替换(找到目标字符串,然后替换掉)
sub()完成替换,返回一个被替换完成之后的字符串
subn()完成替换,还返回被替换的数量,字符串和数组,组成元组返回
import re
sentence = 'Java是很受欢迎的编程语言'
pattern = '[a-zA-Z]+' # [字符集范围] " + "代表: 前面的模式出现1次以上
result = re.sub(pattern,'Python',sentence) # 使用新的Python替代
print(result)
resultn = re.subn(pattern,'Python',sentence)
print(resultn)
Python是很受欢迎的编程语言
('Python是很受欢迎的编程语言', 1)
import re
sentence = 'Java是一门强大的语言,Go前途不错'
pattern = 'Java|Go' # 或关系
result = re.sub(pattern,'Python',sentence)
print(result)
Python是一门强大的语言,Python前途不错
1.7 split()
作用: 实现分隔字符串
import re
data = '百度,腾讯,阿里,华为,智能天下'
pattern = ','
result = re.split(pattern,data)
print(type(result))
print(result)
<class 'list'>
['百度', '腾讯', '阿里', '华为', '智能天下']
(二) 正则表达式的知识点汇总
介绍正则的知识点,用于编辑正则表达式,
2.1 正则模式中的字符
-
最简单的,任意一个字符串都是一个正则表达式的模式(但是这样的通用性不强,只能匹配一个特定字符串,没有什么意义)
-
匹配一定范围内的单个字符1[abc]: 中括号里面的内容即"或"的关系
-
匹配一定范围内的单个字符2[a-c]: 使用连接符,代表范围,[a-z][0-9]
-
代表单个字符的特殊符号:
-
"."点号: 匹配任意字符(字母,数字,特殊字符,但是换行符除外)
-
\w: 匹配任意字母,数字(比上面的"."少了特殊字符)
-
\d: 匹配任意十进制数字(比上面的\w少了字母)
-
\s: 匹配空白
-
\b: 匹配边界
-
^: 匹配开始
-
$: 匹配结尾
-
注意: 如果要在模式中匹配上面出现的特殊字符,例如: ".","","^","$",需要使用转义字符:\
-
2.2 正则中频数的表示
概括的表示频数
- *: 代表匹配0次或者多次
- +: 代表匹配1次或者多次
- ?: 代表匹配0次或者一次
精确的表示频数
- {n}: 代表前面的模式出现n次
- {m,n}: 代表前面的模式出现m到n次之间
2.3 其它重要知识点
分组
模式中被"()"括起来的内容,是可以被提取的,Python以及各种语言实现了这种功能,group()
模式的逻辑或与否定
-
"|" 代表两个模式的或关系
例如: bat|tmd 可以匹配:bt,bm,bd,at,am,ad,tt,tm,td
同: [bat][tmd]
-
"^" 除匹配字符串的开始之外,如果用在[]中,代表否定的意思
例如: [\d]代表的是一个十进制数,[^\d]代表除十进制数之外的其它模式
正则表达式的扩展表示法
2.4 转义字符与原始字符串
转义字符: \ 在字符串中,转义字符用于输出一些特殊字符,例如:\b,代表的是退格,\n代表换行,\t代表制表符,本质上,字符串的转义字符,是为了打印准备的,所以我们暂且定义: 字面量和打印量
原始字符串: 把字母"r"放在字符串开头,代表这是一个原始字符串,它的作用在于消除字符串和正则表达式之间各自关于转义的歧义,例如: \b在正则中表示边界
在cmd窗口里面,定义一个字符串data = '\',输入data与print(data)得到的是不一样的结果,前者是'\',后者是'',这就是字面量和打印量的区别
这个时候再来解释转义在字符串中和正则中的歧义问题就明了了
data = 'ab\cd' # 现在需要要匹配出data中的\怎么处理
首先,data的字面量,也就是字符串的真实值看似是'ab\cd',其实,你用cmd窗口,直接输出data而不是print(data),会发现,字符串的字面显示: ab\cd
所以要匹配出来data的'',pattern要如何写呢?
pattern1 = ''
pattern2 = '\'
pattern3 = '\\'
结果是第三个,首先pattern是一个字符串,虽然要交给正则表达式引擎去解析,但是终归是一个字符串,那么就要经过字符串的转义处理,第一个语法错误,这个''首先转义了结尾的"'",字符串没有结尾了;第二个,'\'是正确的字符串,经过字符串转义后,字面量是\,传递给正则引擎的时候和打印的时候一样,是'',但是真实的data字面量是'\',肯定匹配不到,于是只能用第三种
小马哥正在为Python的所有常见知识进行汇总, 更会有大量实战项目
点击--> 全栈工程师养成---Python内容导航页 <--查看所有Python内容
网友评论