01_re正则表达式
正则表达式,是一个特殊的字符串, 是对一类字符串的描述 ( 怎么描述一类字符: 普通字符+元字符+重复)
检测给定的字符串,是否和正则表达式描述的字符串相匹配
举例:
1) 检查一串数字是否是电话号码
2) 检测一个字符串是否符合email的标准
3) 把一个文本中的指定单词替换为另一个单词
Python提供的则这则表达式模块: re
普通字符: 具体的一个个字符
元字符: 表示一类字符
\d 匹配0~9的任意一个数字字符
\D 匹配1个非数字字符
\w 匹配1个数字,字母,下划线, [A-Za-z0-9_] (单词字符)
\W 匹配1个非单词字符(空格,\n, \r, \t, 也是非单词字符)
\s 匹配1个\n, \r, \t, 空格 (空白字符)
\S 匹配1个非空白字符
. 匹配除换行符\n之外的所有字符
{n} 修饰前面的元字符或普通字符,表示重复n次
[a-z]{3} 3个a到z的任意字符
{n,m} 修饰前面的元字符或普通字符,最小重复次数为n, 最大重复次数为6
[a-z]{3,6} 默认python会贪婪匹配,尽可能多的匹配,看6个连续字符是否存在,没有则看5个连续字符是否存在,以此类推
[a-z]{3,6}? 手工指定非贪婪方式进行匹配,尽可能少的匹配: 有3个连续的字符匹配到就做为1个结果字符串返回
* 匹配*前面的单个字符, 0次或无限多次
+ 匹配+前面的单个字符,1次或无限多次
? 匹配?前面的单个字符,0次或1次 (python? --> pythonn ->返回结果:python(也是贪婪匹配)
经常用于去重(python? -> pythonnnnnn -> 返回结果:python)
?有两种用法,手工指定非贪婪,重复0次或1次,重点是?前面修饰的是{n,m},还是字符(普通字符/元字符)
^ $
^\d{4,8}$, ^, 字符串的开始, 字符串必须以数字字符开头
$, 字符串结尾,最多连续8个数字字符后,字符串就结束,后面不能再有更多的字符
这个例子的含义:4到8个连续数字字符
[nm] 匹配字符n或者字符m
[^nm] 匹配不是字符n和不是字符m的其他字符
[n-m] 匹配n到m的任意一个字符
方法: 查找所有匹配的子串
findall(pattern, string, flags=0) 返回1个list, string中匹配pattern的所有子串,没有则返回空list
flags 匹配模式参数
flags=re.I 忽略大小写来匹配
flags=re.I | re.S 多个模式一起用,re.S( .将匹配所有的字符,包括\n)
方法: 匹配并替换
sub(pattern, replace, string, count=0, flags=0) 将string中所有匹配pattern的子串,替换为replace,生成新的string返回
count=n, 从做到右最多替换n次
count=0, 全部替换,不限定替换次数
replace还可以传入1个函数(意义:根据不同的匹配子串,替换为不同的值)
import re
language = 'C|C#|C++|Python|Java|Scala|Go'
pattern = 'C[#+]*'
replace = 'Go'
result = re.sub(pattern,replace,language) # 替换后生成新字符串,原始字符串并不改变(字符串不可改变)
print(result)
# replace传入函数
def convert(value):
pass
result = re.sub(pattern,convert,language)
print(result) # '|||Python|Java|Scala|Go'
运行机制:python会将匹配到的子串,作为convert函数的形参传入,convert函数的返回值将被作为替换字符,生成新字符串
由于convert没有返回任何值,匹配到的字符会被替换为 空字符
说明: 本质上是将匹配到的子串,生成1个匹配实例传入
# replace传入函数
def convert(value):
print(value) # <_sre.SRE_Match object; span=(0, 1), match='C'>
print(value.group()) # value.group(), 返回匹配到的子串内容
result = re.sub(pattern,convert,language)
print(result) # '|||Python|Java|Scala|Go'
# 将函数作为参数传入re.sub (实例2)
def convert(value):
"""
匹配到的大于6的数字字符,替换为9
匹配到的小于6的数字字符,替换为0
“”“
match = value.group()
if isinstance(int(match), int) and int(match) >= 6:
return '9'
elif isinstance(int(match),int) and int(match) < 6:
return '0'
方法: re.match
match(pattern, string, flags=0) 从string的首字符开始匹配,找到第一个匹配结果,就返回1个match实例,或者None
区别于findall: 1)从第一个字符开始匹配 2)只找1个匹配结果 3)返回结果是match实例
import re
s = 'ABC123788DEF'
pattern = '\d'
result = re.match(pattern, s)
print(result) # None,因为开头没有数字
方法: re.search
search(pattern, string, flags=0) 搜索整个string,找到第一个匹配结果,就返回1个match实例,或者None
区别于findall: 1) 只找1个匹配结果 2)返回结果是match实例
import re
s = 'ABC123788DEF'
pattern = '\d'
result = re.search(pattern, s)
print(result) # result, 是匹配实例
print(result.group()) # '1', 只匹配1个
分组 group
1、组括号 -- pattern中的分组
(python){3} ()内的字符是且的关系,[]内的字符是或的关系
2、groups() -- 获取匹配对象中的各个分组
group() -- 获取匹配对象中个整个匹配结果, group(0)
# 获取匹配结果中的指定部分,group()
import re
s = 'life is short, i use python'
pattern = 'life(.*)python' # pattern中的分组
result = re.search(pattern,s)
print(result) # 匹配对象
print(result.group()) # 获取整个匹配结果,默认参数=0,将整个结果作为1个group返回
print(result.group(1)) # 获取匹配结果中的第一个分组(从左往右)
print(result.groups()) # 获取结果中的所有分组, tuple实例
常见正则表达式参考:
http://www.cnblogs.com/zxin/archive/2013/01/26/2877765.html