正则表达式

就其本质而言,正则表达式(或 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")
['', '']

Python开发基础-Day14正则表达式和re模块的更多相关文章

  1. Python开发基础-Day15正则表达式爬虫应用,configparser模块和subprocess模块

    正则表达式爬虫应用(校花网) import requests import re import json #定义函数返回网页的字符串信息 def getPage_str(url): page_stri ...

  2. Python开发基础-Day13模块2

    sys模块 sys模块提供了一系列有关Python运行环境的变量和函数. #重点记忆 sys.argv #命令行参数List,第一个元素是程序本身路径 sys.exit(n) #退出执行的程序未见,正 ...

  3. Python开发【第*篇】【模块】

    模块分为三种: 自定义模块 第三方模块 内置模块 1.模块导入 import model from model.xx.xx import xx from model.xx.xx import xx a ...

  4. 还在用Alpine作为你Docker的Python开发基础镜像?其实Ubuntu更好一点

    原文转载自「刘悦的技术博客」https://v3u.cn/a_id_173 一般情况下,当你想为你的Python开发环境选择一个基础镜像时,大多数人都会选择Alpine,为什么?因为它太小了,仅仅只有 ...

  5. python基础之正则表达式和re模块

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

  6. python基础之 正则表达式,re模块

    1.正则表达式 正则表达式:是字符串的规则,只是检测字符串是否符合条件的规则而已 1.检测某一段字符串是否符合规则 2.将符合规则的匹配出来re模块:是用来操作正则表达式的 2.正则表达式组成 字符组 ...

  7. Python开发基础-Day16import模块导入和包的调用

    模块概念 在Python中,一个.py文件就称之为一个模块(Module).使用模块组织代码,最大的好处是大大提高了代码的可维护性 模块一共三种:python标准库.第三方模块.应用程序自定义模块. ...

  8. Python开发基础-Day12模块1

    time模块 在Python中,通常有这三种方式来表示时间:时间戳.元组(struct_time).格式化的时间字符串: (1)时间戳(timestamp) :通常来说,时间戳表示的是从1970年1月 ...

  9. Python开发基础-Day31 Event对象、队列和多进程基础

    Event对象 用于线程间通信,即程序中的其一个线程需要通过判断某个线程的状态来确定自己下一步的操作,就用到了event对象 event对象默认为假(Flase),即遇到event对象在等待就阻塞线程 ...

随机推荐

  1. log4net 按照日期备份日志

    配置: <logger name="Log.All">   <level value="INFO" />   <appender- ...

  2. Item27--优先考虑泛型方法

    类型推导:发生在以下三个地方.1.Java编译器根据泛型方法传入的参数,推导出具体的类型.2.Java编译器,根据泛型构造器传入的类型来推导出实际要构造的实例类型.3.Java编译器根据表达式的目标类 ...

  3. 【BZOJ】3626 [LNOI2014]LCA

    [算法]树链剖分+线段树(区间加值,区间求和) [题解]http://hzwer.com/3891.html 中间不要取模不然相减会出错. 血的教训:线段树修改时标记下传+上传,查询时下传.如果修改时 ...

  4. 使用TSQL语句操作MySQL数据库

    使用TSQL语句创建数据库 以前用的是鼠标在界面上手动创建,这样创建会比较麻烦,而且还会经常出问题.在其它电脑上要用的话还需要重复操作.所以要使用程序代码操作,能通过代码的就不用手动操作. 在数据库界 ...

  5. AndroidStudio创建jinLibs文件夹

    在文件中的buildTypes节点下添加 sourceSets.main {          jniLibs.srcDir 'libs'      } 如图

  6. Python自动化运维 - Django(二)Ajax基础 - 自定义分页

    Ajax基础 AJAX 不是新的编程语言,而是一种使用现有标准的新方法. AJAX 是与服务器交换数据并更新部分网页的艺术,在不重新加载整个页面的情况下. 什么是Ajax AJAX = 异步 Java ...

  7. python基础===成员访问__len__()和__getitem__()

    class A: def __init__(self,*args): self.name = arg pass def __len__(self): return len(self.name) a = ...

  8. monkey测试===什么是monkey测试(系列一)转

    本文转自:http://www.cnblogs.com/liu-ke/p/4353926.html Monkey工具使用 一. 什么是Monkey Monkey是Android中的一个命令行工具,可以 ...

  9. 1.Python3标准库--前戏

    Python有一个很大的优势便是在于其拥有丰富的第三方库,可以解决很多很多问题.其实Python的标准库也是非常丰富的,今后我将介绍一下Python的标准库. 这个教程使用的书籍就叫做<Pyth ...

  10. 关于 拼接 url 连接 参数的问题(爬虫)。

    比如这里 我找的 后台请求的json的链接: 第一页: http://www.igoldenbeta.com:8080/cn-jsfund-server-mobile/bkt/api?appkey=1 ...