正则表达式

就其本质而言,正则表达式(或 re)是一种小型的、高度专业化的编程语言,(在Python中)它内嵌在Python中,并通过 re 模块实现。正则表达式模式被编译成一系列的字节码,然后由用 C 编写的匹配引擎执行。

字符匹配(普通字符,元字符):

1 普通字符(完全匹配):大多数字符和字母都会和自身匹配

 >>> import re
>>> res='hello world good morning'
>>> re.findall('hello',res)
['hello']

2 元字符(模糊匹配):. ^ $ * + ? { } [ ] | ( ) \

元字符

.  通配符,匹配一个除了换行符的任意字符,中间如果有换行符也不会跳过换行符,只是无法匹配

 >>> import re
>>> str1="hello\n,张三"
#re.findall()方法,第一个元素为匹配规则,第二个元素为字符串,返回的是所有匹配项的列表,re下的方法后面详细说明
>>> re.findall("l",str1) #遍历匹配l,如果匹配到,则输出为列表的一个元素
['l', 'l']
>>> re.findall("h.",str1)   #匹配h开头,后面包含任意字符除换行符的两个字符
['he']
>>> re.findall("hello.",str1)  #因为hello后的字符是换行符,所以匹配不到
[]
>>> re.findall("张.",str1)    #包含的字符串在哪个位置匹配都可以
['张三']

^  开始匹配,只匹配字符串的开头,开头如果没有,后边不会再进行匹配

 >>> re.findall("^hello",str1)  #开头有hello所以匹配成功
['hello']
>>> re.findall("^llo",str1)    #开头没有llo,匹配失败
[]

$  结尾匹配,只匹配结尾

 >>> re.findall("llo$",str1)    #该字符串以三结尾
[]
>>> re.findall("三$",str1)
['三']
>>> re.findall("张三$",str1)    #可匹配多个字符
['张三']
>>> re.findall("张.$",str1)    #不同的元字符联用
['张三']

重复功能元字符

?  表示?前一个字符或组可有可无,范围即0次或1次

 >>> re.findall("ho?el",str1)  #o可有可无,匹配hel
['hel']
>>> re.findall("he?l",str1)  #e可有可无,有的时候匹配hel
['hel']
>>> re.findall("he?el",str1)  #第一个e可有可无,没有的时候匹配hel
['hel']

*  表示*前面一个字符或组的重复范围,范围从0开始到正无穷,[0,+∞]

 >>> str2=""
>>> re.findall("1*",str2)  #1*表示字符1出现0次或多次,从字符串依次匹配,如果不是1就用空补全
['', '', '', '', '', '', '', '', '', '', '', '', '', '']
>>> re.findall("11*",str2)  #11*表示第二个字符1出现0次或多次,第一个字符1已经固定
['', '', '']

+  类似与*,表示+前面一个字符或组的重复范围,范围从1开始到正无穷,[1,+∞]

 >>> re.findall("11+",str2)  #11+表示第二个1必须是出现1次或多次
['', '', '']
>>> re.findall("1+",str2)  #1+表示必须出现一次1及以上
['', '', '']

{}  {n,m},指定范围,不指定m表示从n到无穷,只有一个n是只能是这么多次

 >>> str2="1113388234234"  
>>> re.findall("1{4}",str2)  #按照字符1重复4次匹配,共匹配成功5次
['', '', '', '', '']
>>> re.findall("3{2}",str2)  #匹配出现2次3的字符串
['']
>>> re.findall("3{1,3}",str2)  #匹配出现1到3次3的情况
['', '', '']
>>> re.findall("1{1,}",str2)  #匹配出现1至少一次的情况
['', '', '']

转义字符

\  反斜杠后边跟元字符去除特殊功能,反斜杠后边跟普通字符实现特殊功能

\d  匹配任何十进制数;      它相当于类 [0-9]。
\D 匹配任何非数字字符; 它相当于类 [^0-9]。
\s 匹配任何空白字符; 它相当于类 [ \t\n\r\f\v]。
\S 匹配任何非空白字符; 它相当于类 [^ \t\n\r\f\v]。
\w 匹配任何字母数字汉字字符; 它相当于类 [a-zA-Z0-9_]。
\W 匹配任何非字母数字汉字字符; 它相当于类 [^a-zA-Z0-9_]
\b 匹配一个特殊字符边界,比如空格 ,&,#等

字符串:包含特殊字符、数字、大小写字母及汉字

 >>> str3='123456  7890@#$abcd  efg!%&*HIJKLMN陈'

\d  匹配十进制数

 >>> re.findall("\d",str3)
['', '', '', '', '', '', '', '', '', '']

\D  匹配非数字字符

 >>> re.findall("\D",str3)
[' ', ' ', '@', '#', '$', 'a', 'b', 'c', 'd', ' ', ' ', 'e', 'f', 'g', '!', '%', '&', '*', 'H', 'I', 'J', 'K', 'L', 'M', 'N', '陈']

\s  匹配任何空白字符

>>> re.findall("\s",str3)
[' ', ' ', ' ', ' ']

\S  匹配任何非空白字符

 >>> re.findall("\S",str3)
['', '', '', '', '', '', '', '', '', '', '@', '#', '$', 'a', 'b', 'c', 'd', 'e', 'f', 'g', '!', '%', '&', '*', 'H', 'I', 'J', 'K', 'L', 'M', 'N', '陈']

\w  匹配任何字母数字汉字字符

 >>> re.findall("\w",str3)
['', '', '', '', '', '', '', '', '', '', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'H', 'I', 'J', 'K', 'L', 'M', 'N', '陈']

\W  匹配任何非字母数字汉字字符

 >>> re.findall("\W",str3)
[' ', ' ', '@', '#', '$', ' ', ' ', '!', '%', '&', '*']

\b  匹配一个特殊的字符边界,注意:因为\b和py解释器有冲突,所以需要加上r表示以源生字符方式传送给re模块解释

 >>> re.findall(r"abcd\b",str3)
['abcd']
>>> re.findall(r"123456\b",str3)
['']

源生字符r示例1:匹配“abc\le”中的‘c\l’,\l无特殊含义

 >>> import re
>>> str4="abc\le"
>>> re.findall('c\l','abc\le') #报错,py解释器会解释一次转义字符,一个\无法解释
>>> re.findall('c\\l','abc\le') #报错,py解释器将两个\解释成一个\传给re模块,re模块
>>> re.findall('c\\\l','abc\le')  #py解释器将三个\解释成\\传给re模块,re模块解释\\转义匹配c\l
['c\\l']    #因为匹配出来的c\l的\是特殊字符,所以py解释器将\转义一次输出
>>> re.findall('c\\\\l','abc\le')  #py解释器将第一个和第二个\解释成一个\,第三个第四个\解释成一个\,共两个\传给re模块
['c\\l']
>>> re.findall(r'c\\l','abc\le')  #py解释器通过r标识,将两个\解释为源生字符直接传给re模块
['c\\l']

源生字符r示例2:匹配“abc\be”中的‘c\b’,\b有特殊含义,为ascii表的退格

 >>> str5="abc\be"
>>> re.findall('c\b','abc\be')
['c\x08']
>>> re.findall('c\\b','abc\be')
['c']
>>> re.findall('c\\\b','abc\be')
['c\x08']
>>> re.findall('c\\\\b','abc\be')
[]
>>> re.findall(r'c\b','abc\be')
['c']
>>> re.findall(r'c\\b','abc\be')
[]
>>> re.findall(r'c\\\b','abc\be')
[]
>>> re.findall(r'c\\\\b','abc\be')
[]
>>> re.findall(r'c\b',r'abc\be')
['c']
>>> re.findall(r'c\\b',r'abc\be')  #当字符串内有特殊含义的字符时候,需要加r转义为源生字符
['c\\b']
>>> re.findall(r'c\\\b',r'abc\be')
['c\\']
>>> re.findall(r'c\\\\b',r'abc\be')
[]

()  分为普通分组和命名分组两种,和的意思,匹配规则的字符串以组的方式划成一个整体,这个整体赋规则匹配字符串

 >>> str6="faefhuknghellohellohelloafeahelloadf"
>>> re.findall("(hello)+",str6)  #将hello组成一个整体进行+规则
['hello', 'hello']  #因为优先级的限制,只能显示分组内的内容
>>> re.findall("(?:hello)+",str6)
['hellohellohello', 'hello']  #?:是一个格式,取消优先级限制,将匹配到的所有显示出来

分组一般配合re.search()和re.match()方法调用

re.search()格式和findall相同,但是其返回的是一个对象,通过调用对象的group方法返回具体的值,re.search()只会匹配一次值,匹配到之后将不再向后匹配,即只有一个结果。

 >>> re.search("(hello)+",str6)
<_sre.SRE_Match object; span=(9, 24), match='hellohellohello'>
>>> ret=re.search("(hello)+",str6)
>>> ret.group()
'hellohellohello'

re.match()方法和元字符^的功能类似,匹配字符串开头,返回一个对象,并且也能通过group方法返回具体的值

 >>> str7="hellohellohellonameafeahelloadf"
>>> ret=re.match("(hello)+",str7)  #开头有hello能匹配到
>>> ret.group()
'hellohellohello'
>>> ret=re.match("(name)+",str7)  #开头没有name,匹配不到
>>> ret.group()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'NoneType' object has no attribute 'group'

命名分组:在分组的基础上加上一个名字,通过group方法调用分组名字返回具体的值

 >>> str8="-blog-aticles-2015-04"
>>> ret=re.search(r"-blog-aticles-(?P<year>\d+)-(?P<month>\d+)",str8)  #?P是定义命名的格式,<>内是名字
>>> ret.group('year')
''
>>> ret.group('month')
''

[]  字符集,中括号内的字符集合,关系为或,即匹配括号内任意一个字符即可,字符集内的-^\三个字符具有特殊意义,其他字符丧失原来的特殊意义。

 >>> str9="adf13415aggae8657dfc" 
>>> re.findall("a[dg]+",str9)  #匹配a开头,后面多余一个d或者g结尾的部分
['ad', 'agg']

字符集内的-表示一个范围

 >>> re.findall("[0-9]+",str9)  #包含0-9数字的字符,匹配+规则
['', '']
>>> re.findall("[a-z]+",str9)
['adf', 'aggae', 'dfc']

字符集内的^表示取反

 >>> re.findall("[^a-z]+",str9)  #不是包含a-z字母的字符,匹配+规则
['', '']
>>> re.findall("[^0-9]+",str9)
['adf', 'aggae', 'dfc']

字符集内的\表示转义

 >>> re.findall("[\d]",str9)
['', '', '', '', '', '', '', '', '']
>>> re.findall("[\w]",str9)
['a', 'd', 'f', '', '', '', '', '', 'a', 'g', 'g', 'a', 'e', '', '', '', '', 'd', 'f', 'c']

|  管道符号,表示或

 >>> str10="www.oldboy.com;www.oldboy.cn;www.baidu.com;"
>>> re.findall("www\.(?:\w+)\.(?:com|cn)",str10)
['www.oldboy.com', 'www.oldboy.cn', 'www.baidu.com']

贪婪匹配和非贪婪匹配(基于重复)

贪婪匹配:按照最长的结果匹配

 >>> str11="dasa11s6666dabccccasd"
>>> re.findall("abc+",str11)  #+表示从范围从1到正无穷,所以多少个c都可以匹配到
['abcccc']
>>> re.findall("\d+",str11)
['', '']

非贪婪匹配:按照最短的结果匹配

 >>> re.findall("\d+?",str11)  #在+后面加?表示取最小范围1
['', '', '', '', '', '']
>>> re.findall("abc+?",str11)
['abc']

非贪婪应用示例:

 >>> str12="<div>yuan<img></div><a href=""></div>"
>>> re.findall("<div>.*?</div>",str12)  #匹配到第一个</div>
['<div>yuan<img></div>']

非贪婪匹配规则:

 *? 重复任意次,但尽可能少重复
+? 重复1次或更多次,但尽可能少重复
?? 重复0次或1次,但尽可能少重复
{n,m}? 重复n到m次,但尽可能少重复
{n,}? 重复n次以上,但尽可能少重复

.*?用法:

 . 是任意字符
* 是取 0 至 无限长度
? 是非贪婪模式。
合在一起就是取尽量少的任意字符,一般不会这么单独写,他大多用在:“.*?a”,就是取前面任意长度的字符,到最后一个 a 出现

re模块方法

re.findall()方法:匹配所有,将匹配到的结果全部按照列表方式返回

re.search()方法:返回一个对象,通过group方法调用具体值,示例见分组部分,匹配到第一个就不再往下继续匹配了,没匹配到返回一个None

re.match()方法:只在字符串开始的位置匹配,返回的是一个对象,通过group方法调用具体值,示例见分组部分

re.split()方法:分割,以列表方式返回,中间用正则模糊匹配,可以限定分割次数

 >>> str13="hello23world12my7name"
>>> re.split("\d+",str13)  #以数字为分割线,返回其他值
['hello', 'world', 'my', 'name']
>>> re.split("(\d+)",str13)  #同时返回分割线
['hello', '', 'world', '', 'my', '', 'name']
>>> re.split("\d+",str13,1)  #分割一次
['hello', 'world12my7name']

特殊情况,分割出空

 >>> re.split("l","hello bob")
['he', '', 'o bob']

re.sub()方法:替换,格式为:规则-替换内容-字符串-计数限定次数

 >>> str14="hello 123 123 name world my name "
>>> re.sub("\d+","A",str14)
'hello A A name world my name '
>>> re.sub("\d","A",str14)
'hello AAA AAA name world my name '
>>> re.sub("\d","A",str14,3)
'hello AAA 123 name world my name '

re.subn():类似于sub,但是以元组返回,并且返回替换次数

 >>> re.subn("\d","A",str14,3)
('hello AAA 123 name world my name ', 3)

re.finditer():返回一个迭代器,调用也是要group方法

 >>> ret=re.finditer("\d+","dasfjk324khk4234kj234hkj234hkj234kj234k2j34hk2j3h4")
>>> print(ret)
<callable_iterator object at 0x000001CE69609470>
>>> print(next(ret))
<_sre.SRE_Match object; span=(6, 9), match=''>
>>> print(next(ret).group())  #因为已经迭代了一次,所以返回第二个值
4234

re.compile():编译规则,以编译对象的方式调用,频繁调用同一个规则时候使用

 >>> num_rule=re.compile('\d+')
>>> print(num_rule,type(num_rule))
re.compile('\\d+') <class '_sre.SRE_Pattern'>
>>> num_rule.findall("hello 123 3241")
['', '']

最新文章

  1. jQuery获取短信验证码+倒计时实现
  2. hbase-site.xml中HBASE_CLASSPATH 的设置
  3. (zz)linux awk
  4. 免费而优秀的图表JS插件
  5. position置顶或某固定位置 兼容ie6ie7
  6. SAP中寄售处理
  7. java作用域public ,private ,protected 及不写时的区别(转)
  8. UVA 10806 Dijkstra, Dijkstra.
  9. 对于一些css样式的巧妙方法进行总结。
  10. 从“跳一跳”来看微信小程序的未来
  11. Windows7安装Pygame软件
  12. 解析Object.defineProperty的作用
  13. NodeJs 使用 multer 实现文件上传
  14. VM下如何装虚拟机?
  15. 关于Natively Compiled Stored Procedures的优化
  16. 04: nginx部署vue
  17. BZOJ3500 : PA2008 Cliquers
  18. 第三十二章 elk(3)- broker架构 + 引入logback
  19. 运行Virtualbox去安装系统时出错:Failed to open a session for the virtual machine,Unable to load R3 module xxxx/VBoxDD.DLL(VBoxDD)
  20. 第三百九十节,Django+Xadmin打造上线标准的在线教育平台—Django+cropper插件头像裁剪上传

热门文章

  1. 【BZOJ】3790 神奇项链
  2. Achain 钱包部署
  3. idea编写的java代码,在cmd运行乱码解决方案
  4. 编写jquery Plugin
  5. 【转】linux下杀死进程
  6. Python模块学习 - Functools
  7. bootstrap-select属性
  8. 【设计模式】迭代器模式(Iterator )
  9. 自动安装jar包到本地仓库
  10. Vue优化首屏加载