正则表达式
正则表达式是一个特殊的字符序列,用于判断一个字符串是否与我们所设定的字符序列匹配,也就是检查一个字符串是否与某种模式匹配。
第一步
a = 'kobe bryant'
print('是否含有"kobe"这个字符串:{0}'.format(a.index('kobe') > -1))
print('是否含有"kobe"这个字符串:{0}'.format('kobe'in a))
是否含有"kobe"这个字符串:True
是否含有"kobe"这个字符串:True
第二步 提供re模块
import re
a = 'kobe bryant'
findall = re.findall('kobe',a)
print(findall)
if len(findall) > 0:
print('True')
else:
print('Not True')
['kobe']
True
正则表达式是用一种描述性的语言来给字符串定义一个规则,符合规则的字符串,就认为它“匹配”了。
第三步 正则表达式的字符集 “[ ]”
- 用 \d 匹配一个数字
- 用 \w 匹配一个字母或数字
- 用 \s 匹配任何空格字符
- 用 \b 匹配任何单词边界
- 用 . 匹配任意字符
import re
a = 'uav,ubv,ucv,uwv,uzv,ucv,uov'
# 取 u 和 v 中间是 a/b/c 的字符
findall = re.findall('u[abc]v',a)
print(findall)
findall2 = re.findall('u[a-c]v',a)
print(findall2)
# 取 u 和 v 中间不是 a/b/c 的字符
re_findall = re.findall('u[^abc]v',a)
print(re_findall)
# 匹配三个字母
findall3 = re.findall('\w\w\w',a)
print(findall3)
['uav', 'ubv', 'ucv', 'ucv']
['uav', 'ubv', 'ucv', 'ucv']
['uwv', 'uzv', 'uov']
['uav', 'ubv', 'ucv', 'uwv', 'uzv', 'ucv', 'uov']
匹配变长的字符
- 用 * 表示任意个字符(包括0个)
- 用 + 表示至少一个字符
- 用 ? 表示0个或1个字符
- 用{n}表示n个字符
- 用{n,m}表示n-m个字符
import re
a = '010 87100000'
findall = re.findall('\d{3}\s+\d{3,8}',a)
print(findall)
['010 87100000']
数量词
{min,max}。如果有逗号而max被省略,则max没有限制。如果逗号和max都被忽略了,重复min次。
import re
a = '1000,666,5555,8888,99,1000000'
# 1000~9999
findall1 = re.findall('([1-9][0-9]{3})[^\d]', a) # 加入[^\d]进行非数值的匹配 ()去掉匹配的逗号
print(findall1)
# 100~99999
findall2 = re.findall('\\b[1-9][0-9]{2,4}\\b', a) # \b为转义字符 \\b 才是单词边界的意思
findall3 = re.findall(r'\b[1-9][0-9]{2,4}\b',a) # 前面加上r 声明了引号中的内容表示该内容的原始含义,避免了多次转义造成的反斜杠困扰。
print(findall2)
print(findall3)
['1000', '5555', '8888']
['1000', '666', '5555', '8888']
['1000', '666', '5555', '8888']
第四步 贪婪匹配与懒惰匹配
贪婪模式 (尽可能多的字符)
它的特性是一次性地读入整个字符串,如果不匹配就吐掉最右边的一个字符再匹配,直到找到匹配的字符串或字符串的长度为0为止
- aabab 用 a .*b 贪婪匹配 匹配整个字符串。
懒惰模式 (尽可能少的字符)
它的特性是从字符串左边开始,试图不读入字符串中的字符进行匹配,失败,则多读一个字符,再匹配,当找到一个匹配时会返回该匹配的字符串,然后再次进行匹配知道字符串结束
- aabab 用a .*?b 懒惰匹配 匹配 aab 和 ab。
import re
a = 'java*&39android##@@python'
# 贪婪
findall = re.findall('[a-z]{4,7}', a)
print(findall)
# 懒惰
re_findall = re.findall('[a-z]{4,7}?', a)
print(re_findall)
['java', 'android', 'python']
['java', 'andr', 'pyth']
贪婪懒惰匹配
re.sub 用于替换字符串中的匹配项
- 共有五个参数 三个必选参数:pattern,repl,string;两个可选参数:count,flags
sub函数
import re
a = 'Python*Android*Java-888'
# 把字符串中的*替换成&字符
sub1 = re.sub('\*','&',a)
print(sub1)
# 把字符串中的第一个*字符替换成&字符
sub2 = re.sub('\*','&',a,1)
print(sub2)
# 把字符串中的*字符替换成&字符,把字符-换成|
def convert(value):
group = value.group()
if(group == '*'):
return '&'
elif(group == '-'):
return '|'
sub3 = re.sub('[\*-]',convert,a)
print(sub3)
Python&Android&Java-888
Python&Android*Java-888
Python&Android&Java|888
re.match函数
尝试从字符串的起始位置匹配一个模式,如果不是起始位置匹配成功的话,match()就返回none。
re.match(pattern,string,flags=0)
re.search函数
扫描整个字符串并返回第一个成功的匹配
re.search(pattern,string,flags=0)
import re
a = re.match(r'^\d{3}\-\d{3,8}$','010-12345')
b = re.match(r'^\d{3}\-\d{3,8}$','010 12345')
print(a)
print(b)
<re.Match object; span=(0, 9), match='010-12345'>
None
match search函数
re.match只匹配字符串的开始,如果字符串开始不符合正则表达式,则匹配失败,函数返回None;而re.search匹配整个字符串,直到找到一个匹配
分字符串 re.split()
'a b c'.split(' ')
['a', 'b', '', '', 'c']
re.split(r'\s+','a b c') # 识别连续的空格
['a', 'b', 'c']
re.split(r'[\s\,]+','a,b, c d') # 识别空格或逗号
['a', 'b', 'c', 'd']
re.split(r'[\s\,\;]+','a,b;;, c ;d')
['a', 'b', 'c', 'd']
分组
提取字串,用()表示的就是要提取的分组(group)
边界匹配符
import re
# 定义了两个组,可以直接从匹配的字符串中提取
m = re.match(r'^(\d{3})-(\d{3,8})$','010-12345') # ^是正则表达式匹配字符串开始位置,$是正则表达式匹配字符串结束位置
print(m)
print(m.group(0))
print(m.group(1))
print(m.group(2))
<re.Match object; span=(0, 9), match='010-12345'>
010-12345
010
12345