d 数字
D 非数字
w 字符(含字母、数字、下划线)
W 非字符(一般指标点、特殊字符及空白等)
s 空白( 等 )
S 非空白(字符、数字、下划线、标点、特殊字符等)
. 匹配除 之外的任意字符
表示边界 ,非字母,非包含,
print(re.search(r'abc',' abcdeft ').group())
#结果:abc
#结果:abc
print(re.search(r'eft',' abcdeft ').group())
#结果:eft
[a-zA-Z] (大小写字母)
[sw] 空白或者字符
{1,3} 指匹配数量 1-3个都满足,贪婪,最多的进行匹配
+ 1个或者多个
* 0个或者多个,如果匹配到0 便不会继续匹配
? 0个或者1个 限制贪婪,如果匹配到0 便不会继续匹配
^如果是 r'^abc' ,则表示 以abc开头的匹配
如果是[^abc],则表示非 abc,即不包含abc的匹配
$ 表示匹配结尾
re.I 忽略大小写
re.M 可以多行匹配,以 分割的多行
re.DOTALL 表示 . 可以匹配包含 在内的所有字符,与re.S是一个意思
以上多个一起使用 用 | 分割,re.M|re.S
前项肯定、后项肯定
print(re.search(r'123(?<=abc)','abc123')) #表示前面是abc的才会匹配
(?=:) #表示后面是:的才会匹配,相当于做了一个边界
一些常用的方法,match,search,findall,finditer,.group(),split,sub
示例代码:
#coding=gbk ''' 1、正则表达式 ''' import re #re.DOTALL 加上这个参数, . 就可以匹配 了 print(re.findall(r'.+','abcbcd ert dfff ',re.DOTALL)) #结果:['abcbcd ert dfff '] #p.flags (?P<sign>.*)是命名分组 p=re.compile(r'(w+)(w+)(?P<sign>.*)',re.DOTALL) print('p.flags:',p.flags) #re.I 忽略大小写 print(re.findall(r'aBc','sefs abcee ABC AbCf gggaBc',re.I)) #结果:['abc', 'ABC', 'AbC', 'aBc'] #p.groups 分组数量 p.groupindex #match 从哪个区间位置开始匹配 print(re.match(r'abc','eeabcttabc',2))##这个有问题,要使用re的编译对象pp pp=re.compile(r'abcw+') print(pp.match('eeabcttabcuu',7)) #结果abcuu #search 同样可以输入初始位置及结束位置 print(pp.search('eeabcttabcyy',7).group()) #结果abcyy #findall 只返回分组内的内容 print(re.findall(r'[a-zA-Z]+(d+)','aa1bn2mj33gh44hhh55')) #结果:['1', '2', '33', '44', '55'] #多个分组则以元组形式返回 print(re.findall(r'([a-zA-Z]+)(d+)','aa1bn2mj33gh44hhh55')) #结果:[('aa', '1'), ('bn', '2'), ('mj', '33'), ('gh', '44'), ('hhh', '55')] print(re.findall(r'(([a-z])(d+)([a-z]))','a1ab2bc3cd4d'))#嵌套分组,先返外层分组内容,然后再返回内部分组 #结果:[('a1a', 'a', '1', 'a'), ('b2b', 'b', '2', 'b'), ('c3c', 'c', '3', 'c'), ('d4d', 'd', '4', 'd')] #整体返回一个元组, #re.M 多行匹配 s='ab212cd efghjj333i erege4343wefw fff' print(re.findall(r'[a-zA-Z]+$',s,re.M)) #结果:['cd', 'i', 'wefw', 'fff'] print(re.finditer(r'd+',s)) for i in re.finditer(r'd+',s): print(i.group()) #split print(re.split(r'd+','one12two34three5554446four78')) #切割出全部字母 s='a 2222 22 b 3344 c 544vv 44 d' print(re.split(r'[ds]+',s)) #切割出全部数字 print(re.split(r'[a-zA-Zs]+',s)) print(''.join(re.split(r'[a-zA-Zs]+',s))) ss=re.split(r'[a-zA-Zs]+',s) print(list(filter(lambda x:x!='',ss))) #可以控制切割次数 ss=re.split(r'[a-zA-Zs]+',s,2) print(list(filter(lambda x:x!='',ss))) #替换re.sub print(re.sub(r'd+','**','one222two333three444four555')) #结果:one**two**three* #替换空白字符、数字为'' print(re.sub(r'[ds]+','','on e22 2tw o333t hree444four555')) #结果:onetwothreefour #替换掉所有标点符号 print(re.sub(r'[^wds]+','','avn,kje,ww')) #结果:avnkjeww #可以指定替换次数 print(re.sub(r'[^wds]+','','avn,kje,ww',1)) #结果:avnkje,ww #通过sub,交换分组的字符串的位置 p=re.compile(r'(w+) (w+)') s='i say,hello world!!' print(p.search(s).group()) #结果:i say print(p.findall(s)) #结果:[('i', 'say'), ('hello', 'world')] print(p.sub(r'2 1',s))#通过sub交换两个单词的位置 def func(m): print('group1:',m.group(1)) print('group2:',m.group(2)) return m.group(1).title()+' '+m.group(2) print(p.sub(func,s)) #s的每一组匹配结果,传入到func处理 import math def multiply(m): print(m) v=int(m.group(0)) print('v:',v) #return str(v*2) return str(math.pi*(v**2)) result=re.sub(r'd+',multiply,'10 20 30 40 50') print(type(result)) print(result)
后向引用 1 代表 前面()分组1的 正则匹配的内容,必须一致 >>> re.search(r"(d{2}) 1",'22 22').group(1) '22' >>> re.search(r"(d{2}) 1","22 21").group(1) Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: 'NoneType' object has no attribute 'group' >>> # 交换.号两边的字符串 ... res = re.sub(r'(.*).(.*)', r'2.1', s) #前项肯定 (?<=abc)d+ 前面是abc的数字 可匹配 >>> re.search(r"(?<=abc)d+","abc123").group() '123' #后项肯定 d+(?=abc) 后面是abc的数字可匹配 >>> re.search(r"d+(?=abc)","123abc").group() '123' 多行匹配注释的例子: s1 ="""char *a="hello world"; char b='c'; /* this is comment */ int c=1; /* this is multiline comment */""" print(re.findall( r'(?<=/*).+?(?=*/)' , s1 ,re.M|re.S)) #前项否定 (?<!abc)d+ 前面不是abc的数字 >>> re.search(r"(?<!abc)d+","a*bc123").group() '123' #后项否定 d+(?!abc) 后面不是abc的数字匹配 >>> re.search(r"d+(?!abc)","123mn").group() '123' #?: 表示()里面的内容 不能用 .group()取到 >>> re.search("a(?:d)c","a1c").group() 'a1c'