一、内置查找函数
在介绍正则表达是之前我们先来介绍一下字符串相关的查找函数 index() ,这个函数的使用和JS的 indexOf() 一模一样,都是查找字符串在某个字符串中首次出现的位置,返回值是首次出现的索引。
我们可以看看下面的示例:
a = 'c|c++|python|php|java|javascript|html'
str_index = a.index('python')
print(str_index) # 打印的结果:6
注意:索引是从0开始,所以返回值有可能是0
在python中正则表达式的性能弱于内置函数的性能,如果实际工作中内置函数可以满足我们对字符数据的操作,尽量使用内置函数。这样既可以节省开发时间,还能提高代码执行效率
二、正则表达式
python提供了一个名为 re 的模块,这个模块可以帮助我们使用正则表达式进行匹配。在使用是我们只需要导入 re 模块即可,具体方式及参数如下:
import re
re.findall('正则表达式','待匹配的字符串','匹配模式')
注意:findall() 正则匹配返回的是一个数组,如果没有匹配到返回的就是一个空数组
findall函数参数一是正则表达式,参数二是待匹配的字符串,参数三是匹配的模式。第三个参数可以是固定的某个模式,如有多个模式共存可以使用 | 进行分割。
关于匹配模式,大致分为一下几种:
re.I :不区分大小写
re.S :允许匹配制表符等特殊字符
正则表达式是由普通字符和元字符组合而成,当然也可以单独使用。普通字符比较简单,都是日常使用的字符。元字符是一些特殊意义的字符,我这里给大家总结了一部分日常工作中常用的元字符:
下面我们简单的介绍一下正则表达式的使用。
2.1 元字符匹配
上面的表格中其实已经列出数字的匹配元字符,我们可以直接通过元字符表达式进行匹配:
import re
a = 'c1c++223234python5465php|java|javascript7u6576html'
result = re.findall('\d',a)
print(res) # 打印结果:['1', '2', '2', '3', '2', '3', '4', '5', '4', '6', '5', '7', '6', '5', '7', '6']
2.2 或方式的匹配
如果我们需要匹配 p 与 t 之间为y或者x的字符时,可以使用 [] 来表示:
import re
a = 'c1c++223234python5465php|java|javascript7u6576html'
res = re.findall('p[yx]t',a)
print(res) # 打印结果:['pyt']
[] 在正则中表示或的意思,但是他只匹配一个字符。正则中我们可以通过 {} 规定匹配的字符数。例如下方的匹配:
import re
a = 'c1c++223234python5465php|java|javascript7u6576html'
res = re.findall('[a-z]{3,6}',a)
print(res) # 打印结果:['python', 'php', 'java', 'javasc', 'ript', 'html']
上述示例中我们通过 {} 规定最少匹配3个字符,最多匹配6个字符。也可以只规定最少匹配的个数,例如:
import re
a = 'c1c++223234python5465php|java|javascript7u6576html'
res = re.findall('[a-z]{3}',a)
print(res) # 打印结果:['pyt', 'hon', 'php', 'jav', 'jav', 'asc', 'rip', 'htm']
2.3 贪婪与非贪婪模式
正则的表达中有一个贪婪与非贪婪的模式,默认是贪婪模式。贪婪模式下,正则会按 {} 中定义的最大匹配的关系进行匹配,而非贪婪模式下则相反,只要匹配的最小关系的值后再继续匹配下一个。
如果需要规定使用非贪婪模式进行匹配,可以在 {} 后面加个 ? 即可。具体方式如下:
import re
a = 'c1c++223234python5465php|java|javascript7u6576html'
res = re.findall('[a-z]{3,6}?',a)
print(res) # 打印结果:['pyt', 'hon', 'php', 'jav', 'jav', 'asc', 'rip', 'htm']
2.4 边界符(^ 与 $)
边界符是用于定义正则匹配的边界。
^ :表示以这个符号后面的字符开始的字符串。
$ :表示以这个字符前面的字符结束的字符串
import re
a = 'c1c++223234python5465php|java|javascript7u6576html'
res = re.findall('^11[0-9a-z]99$',a)
print(res) # 打印结果:[]
上面的案例中我们规定以11开头,并且以99结束,中间的字符可以是0到9之前的数字及a到z之前的所有字母。当然这个俩个边界符也可以单独使用,比如以某个字符开头的字符 ^aaa ,比如以某个字符结尾的字符 999$
2.5 组的概念
在一些特殊情况下,我们需要匹配多个相同字符时,可以使用重复字符串的方式进行匹配,例如:
import re
a = 'pythonpythonpython|php|c#'
re.findall('pythonpythonpython',a)
print(res) # 打印结果:['pythonpythonpython']
对于这种情况正则提供了一个更为简单的方式,以组的方式定义相同元素出现的次数,例如:
import re
a = 'pythonpythonpython|php|c#'
res = re.findall('(python){3}',a)
print(res) # 打印结果:['python']
注意了,其中 {3} 表示组出现的次数
三. 其他正则相关函数
python的 re 模块除了上面介绍的 findall() 方法之外,还提供了一些其他方法。例如使用正则匹配精选替换方法等。
re 模块的正则字符串替换方法为 sub() 。具体用法如下:
import re
a = 'pythonpythonpython|php|c#'
res = re.sub('c#','.net',a)
print(res) # 打印结果:pythonpythonpython|php|.net
参数一:正则匹配的规则
参数二:替换后的字符
参数三:原字符串
参数四:替换的次数。默认是0,表示可以无限制的替换,直至结束。
虽然python提供了这个正则替换方法,但是,如果匹配的字符是一个简单的字符,不需要使用正则时可以直接使用 replace() 方法替换。例如下方案例:
a = 'acfds|python|c#|java|php'
a = a.replace('c#','.net')
print(a) #打印结果:acfds|python|.net|java|php
注意:这个方法和JS中的查找替换函数一样,他不是直接在原字符上进行替换,我们需要使用变量来接收替换后的字符串
除了 sub() 方法之外还提供了 match() 和 search() 这两个方法,用法和 findall() 几乎一样。sub()方法返回的是一个列表,但是这两个方法返回的是一个对象。
此外,这两个方法只会匹配一次,即只要匹配到了正则规则想要的字符就不会继续查找匹配。
import re
a = 'acfds|python|c#|java|php'
res = re.match('c#',a)
print(res) #打印结果:None
res = re.match('a[a-z]*d',a)
print(res) #打印结果:
print(res.group()) #打印结果:acfd
print(res.span()) #打印结果:(0, 4)
match() 方法是从字符串的第一个字符开始匹配,如果匹配不到就放回None。其作用类似与 findall() 的匹配规则是以边界 ^ 开始。
group():获取的是具体的匹配结果
span():获取的匹配结果开始和结束的位置
searh(c) 是从整个字符串上进行匹配查找,例如下方案例:
import re
a = 'python|c#|java|php|acfds'
res = re.search('a[a-z]*d',a)
print(res.group()) #打印结果:acfd
res = re.match('a[a-z]*d',a)
print(res) #打印结果:None
注意:match是从字符串的开头开始匹配的,由于字符串不是以a开头,所以返回的是None
实际工作中,我们一般都是使用 findall() 方法进行正则匹配,毕竟她的功能更加强大。所以我们这里就不做过多介绍。
领取专属 10元无门槛券
私享最新 技术干货