首页 > 技术文章 > 正则表达式

xiaoxiao075 2019-02-01 18:20 原文

\d 数字

\D 非数字

\w 字符(含字母、数字、下划线)

\W 非字符(一般指标点、特殊字符及空白等)

\s 空白(\t  \n  \r   等 )

\S 非空白(字符、数字、下划线、标点、特殊字符等)

.  匹配除 \n之外的任意字符

\b 表示边界 ,非字母,非包含,

print(re.search(r'\babc','    abcdeft   ').group())
#结果:abc
print(re.search(r'eft\b','  abcdeft     ').group())
#结果:eft

[a-zA-Z]  (大小写字母)

[\s\w]  空白或者字符

{1,3} 指匹配数量 1-3个都满足,贪婪,最多的进行匹配

+  1个或者多个

*   0个或者多个,如果匹配到0 便不会继续匹配

? 0个或者1个 限制贪婪,如果匹配到0 便不会继续匹配

^如果是 r'^abc'  ,则表示 以abc开头的匹配

如果是[^abc],则表示非 abc,即不包含abc的匹配

$ 表示匹配结尾

re.I  忽略大小写

re.M  可以多行匹配,以\n分割的多行

re.DOTALL 表示 . 可以匹配包含\n在内的所有字符,与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  加上这个参数, . 就可以匹配\n了  

print(re.findall(r'.+','abcbcd\nert\ndfff\n',re.DOTALL))

#结果:['abcbcd\nert\ndfff\n']

#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'abc\w+')
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\nefghjj333i\nerege4343wefw\nfff'
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'[\d\s]+',s))
#切割出全部数字
print(re.split(r'[a-zA-Z\s]+',s))
print(''.join(re.split(r'[a-zA-Z\s]+',s)))

ss=re.split(r'[a-zA-Z\s]+',s)
print(list(filter(lambda x:x!='',ss)))

#可以控制切割次数
ss=re.split(r'[a-zA-Z\s]+',s,2)
print(list(filter(lambda x:x!='',ss)))

#替换re.sub

print(re.sub(r'\d+','**','one222two333three444four555'))
#结果:one**two**three*

#替换空白字符、数字为''
print(re.sub(r'[\d\s]+','','on\n   e22\t    2tw\r o333t\n   \three444four555'))
#结果:onetwothreefour

#替换掉所有标点符号
print(re.sub(r'[^\w\d\s]+','','avn,kje,ww'))
#结果:avnkjeww

#可以指定替换次数
print(re.sub(r'[^\w\d\s]+','','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'

 

 

推荐阅读