Python正则表达式

来源:互联网 发布:上海网络推广铭心 编辑:程序博客网 时间:2024/06/08 19:01

1、正则规则

      单字符匹配

字符.匹配任意1个字符(除了\n)[ ]匹配[ ]中列举的字符\d匹配数字,即0-9\D匹配非数字,即不是数字\s匹配空白,即 空格,tab键  \r \n \t\S匹配非空白\w匹配单词字符,即即字符、数字、下划线,字符包括各个国家的文字(python2中只能匹配[A-Za-z0-9_])\W匹配非单词字符

      表示数量

字符功能*匹配前一个字符出现0次或者无限次,即可有可无+匹配前一个字符出现1次或者无限次,即至少有1次?匹配前一个字符出现1次或者0次,即要么有1次,要么没有{m}匹配前一个字符出现m次{m,}匹配前一个字符至少出现m次{m,n}匹配前一个字符出现从m到n次      

      表示边界

字符功能^匹配字符串开头$匹配字符串结尾\b匹配一个单词的边界,不能匹配空格\B匹配非单词边界

    

      匹配分组

字符功能|匹配左右任意一个表达式(ab)将括号中字符作为一个分组\num引用分组num匹配到的字符串(?P<name>)分组起别名(?P=name)引用别名为name分组匹配到的字符串

2、Python中的正则:re模块

       1.re中的方法

pattern:正则表达式;str:源字符串,repl:替换的字符串
re.compile(pattern): 编译一个正则表达式模式,返回一个模式对象。
re.match(pattern,str): 只匹配符合pattern开头的字符串,匹配成功返回匹配对象(Match Object),否则返回None(注意不是空字符串"")。
re.search(pattern,str): 在str中搜索匹配的字符串,只匹配一次,返回Match对象,匹配失败返回None
re.findall(pattern,str): 搜索所有满足正则表达式的字符串,返回list,匹配失败返回[]
re.finditer(pattern,str): 搜索所有满足正则表达式的字符串,返回iter迭代器,其值是Match对象,匹配失败返回空的迭代器。
re.sub(pattern,repl,str,count=0): 将符合正则的字符串替换为repl,count替换的次数,默认全部替换,有findall()的功能
re.split(pattern, string, maxsplit=0): 根据模式分割源字符串,返回包含结果子字符串的列表。如果在模式中使用括号,将模式中的组也作为结果的一部分返回。maxsplit:设置最大分割数。

示例:compile()

In [2]: pat = re.compile(r'\d')In [3]: pat.match('123')Out[3]: <_sre.SRE_Match object; span=(0, 1), match='1'>In [4]: pat.search('123')Out[4]: <_sre.SRE_Match object; span=(0, 1), match='1'>In [5]: pat.findall('123')Out[5]: ['1', '2', '3']

示例:match()

In [28]: re.match(r"\d+", "阅读12次数为 9999,a=123")NoneIn [29]: re.match(r"\d+", "12阅读12次数为 9999,a=123")Out[29]: <_sre.SRE_Match object; span=(0, 2), match='12'>

示例:search()

In [11]: a =  re.search(r"\d+", "阅读12次数为 9999,a=123")In [12]: aOut[12]: <_sre.SRE_Match object; span=(2, 4), match='12'>In [13]: a.group()Out[13]: '12'

示例:findall()
In [14]: li =  re.findall(r"\d+", "12300阅读12次数为 9999,a=123")In [15]: liOut[15]: ['12300', '12', '9999', '123']

示例:finditer()
In [17]: ite =  re.finditer(r"\d+", "12300阅读12次数为 9999,a=123")In [18]: iteOut[18]: <callable_iterator at 0x7ff94cc0e0f0>In [21]: for i in ite:   ....:     print(i)   ....:<_sre.SRE_Match object; span=(7, 9), match='12'><_sre.SRE_Match object; span=(13, 17), match='9999'><_sre.SRE_Match object; span=(20, 23), match='123'>

示例:sub()
In [41]: su = re.sub(r"\d+",'2',"12300阅读12次数为 9999,a=123")In [42]: suOut[42]: '2阅读2次数为 2,a=2'In [43]: su = re.sub(r"\d+",'2',"12300阅读12次数为 9999,a=123",2)In [44]: suOut[44]: '2阅读2次数为 9999,a=123'

示例:split()
In [30]: str = 'info:xiaoZhang 33 shandong'In [31]: t = re.split(r':| ',str) #以:或 空格分割In [32]: tOut[32]: ['info', 'xiaoZhang', '33', 'shandong']In [35]: t = re.split(r'(:| )',str) #如果使用(),将匹配模式也作为结果的一部分返回In [36]: tOut[36]: ['info', ':', 'xiaoZhang', ' ', '33', ' ', 'shandong']In [49]:str = 'info:xiaoZhang 33 shandong:999'In [49]: t = re.split(r':',str,maxsplit=1) #设置最大分割数,默认全部分割,这里是分割一次。In [50]: tOut[50]: ['info', 'xiaoZhang 33 shandong:999']In [51]: t = re.split(r':',str,maxsplit=0)In [52]: tOut[52]: ['info', 'xiaoZhang 33 shandong', '999']

注意点:
1.sub():repl可以是字符串,也可以是可调用的对象;
sub将匹配的结果作为参数传递给调用的对象,对象的返回值作为替换的字符串。返回值必须为str类型

示例:sub处理匹配的内容
需求:将匹配到的阅读次数加1

import redef add(temp):    print(temp) #匹配的Match对象    t = int(temp.group())+1    return str(t)    a = re.sub(r'\d+',add,'pyhton:123,java=20,php=19')print(a)#结果<_sre.SRE_Match object; span=(7, 10), match='123'><_sre.SRE_Match object; span=(16, 18), match='20'><_sre.SRE_Match object; span=(23, 25), match='19'>'pyhton:124,java=21,php=20'

2.findall():如果pattern进行了分组,findall会返回符合组里的正则表达式的字符串,多个分组以元组的形式返回。

示例:findall():返回[(),]的形式

In [22]: str = '''   ....: <p>技术要求:</p>   ....: <p>1、一年以上 Python 开发经验,掌握面向对象分析和设计,了解设计模式</p>   ....: <p>2、掌握HTTP协议,熟悉MVC、MVVM等概念以及相关WEB开发框架</p>   ....: <p>3、掌握关系数据库开发设计,掌握 SQL,熟练使用 MySQL/PostgreSQL 中的一种<br></p>   ....: <p>4、掌握NoSQL、MQ,熟练使用对应技术解决方案</p>   ....: <p>5、熟悉 Javascript/CSS/HTML5,JQuery、React、Vue.js</p>   ....: '''#返回匹配<p></p>里的内容   In [24]: re.findall(r'<p>(.*)</p>',str)Out[24]:['技术要求:', '1、一年以上 Python 开发经验,掌握面向对象分析和设计,了解设计模式', '2、掌握HTTP协议,熟悉MVC、MVVM等概念以及相关WEB开发框架', '3、掌握关系数据库开发设计,掌握 SQL,熟练使用 MySQL/PostgreSQL 中的一种<br>', '4、掌握NoSQL、MQ,熟练使用对应技术解决方案', '5、熟悉 Javascript/CSS/HTML5,JQuery、React、Vue.js']#返回符合(\d+)和(.*)的字符串,并放在一个元组中In [23]: re.findall(r'<p>(\d+)、(.*)</p>',str)Out[23]:[('1', '一年以上 Python 开发经验,掌握面向对象分析和设计,了解设计模式'), ('2', '掌握HTTP协议,熟悉MVC、MVVM等概念以及相关WEB开发框架'), ('3', '掌握关系数据库开发设计,掌握 SQL,熟练使用 MySQL/PostgreSQL 中的一种<br>'), ('4', '掌握NoSQL、MQ,熟练使用对应技术解决方案'), ('5', '熟悉 Javascript/CSS/HTML5,JQuery、React、Vue.js')]

3、原始字符串

    Python中字符串前面加上 r 表示原生字符串,不解析\
  

 In [90]: r'\\a'    Out[91]: '\\\\a'    In [92]: a = r'\b'    In [100]: re.match(r'\\b',a)    Out[100]: <_sre.SRE_Match object; span=(0, 2), match='\\b'>    In [94]: re.match(r'\b',a)    In [95]: ret = re.match(r'\b',a)    In [96]: ret.group()    ---------------------------------------------------------------------------    AttributeError                            Traceback (most recent call last)    <ipython-input-96-57f777bf89c0> in <module>()    ----> 1 ret.group()    AttributeError: 'NoneType' object has no attribute 'group'    #虽然a = r'\b',但实际a='\\b',所以匹配a的时候是匹配的\\b    In [93]: a    Out[93]: '\\b'

4、python贪婪和非贪婪

Python里数量词默认是贪婪的(在少数语言里也可能是默认非贪婪),总是尝试匹配尽可能多的字符;
非贪婪则相反,总是尝试匹配尽可能少的字符。
在"*","?","+","{m,n}"后面加上?,使贪婪变成非贪婪。

示例:

>>> s="This is a number 234-235-22-423">>> r=re.match(".+(\d+-\d+-\d+-\d+)",s)>>> r.group(1)'4-235-22-423'>>> r=re.match(".+?(\d+-\d+-\d+-\d+)",s)>>> r.group(1)'234-235-22-423'>>>

解析:
正则表达式模式中使用到通配字,那它在从左到右的顺序求值时,会尽量“抓取”满足匹配最长字符串,在我们上面的例子里面,“.+”会从字符串的启始处抓取满足模式的最长字符,其中包括我们想得到的第一个整型字段的中的大部分,“\d+”只需一位字符就可以匹配,所以它匹配了数字“4”,而“.+”则匹配了从字符串起始到这个第一位数字4之前的所有字符。
解决方式:非贪婪操作符“?”,这个操作符可以用在"*","+","?"的后面,要求正则匹配的越少越好。

提取img里的url地址

In [14]: str ='<img src="https://images.apple.com/v/iphone-7/d/images/overview/movies_video_large.jpg" alt="">'In [18]: t = re.search(r'src="(.*)"',str)In [28]: t.group()Out[28]: 'src="https://images.apple.com/v/iphone-7/d/images/overview/movies_video_large.jpg" alt=""'In [29]: t.group(1)Out[29]: 'https://images.apple.com/v/iphone-7/d/images/overview/movies_video_large.jpg" alt="'In [30]: t = re.search(r'src="(.*?)"',str)In [31]: t.group(1)Out[31]: 'https://images.apple.com/v/iphone-7/d/images/overview/movies_video_large.jpg'

5、Match对象
    Match Object:
    dir(result):查看Match中的属性和方法
    方法:
    group(index):通过索引或名称返回匹配的子组(s)。为0返回整个匹配。

    groups():返回所以组匹配的字符串

    groupdict():返回组名和组匹配的字符串的键值对

In [47]: t = re.match(r'a(.*)','aBC')In [48]: t.groups()Out[48]: ('BC',)In [49]: t.group()Out[49]: 'aBC'In [50]: t.group(1)Out[50]: 'BC'In [51]: t.groupdict(1)Out[51]: {}In [52]: t = re.match(r'a(?P<n1>.*)','aBC')In [53]: t.groupdict(1)Out[53]: {'n1': 'BC'}

6、匹配分组

示例1:|  或

需求:匹配出0-100之间的数字


示例2:( ) 分组

需求:匹配出163、126、qq邮箱之间的数字



示例3:\number

需求:匹配出<html>hh</html>


需求:匹配出<html><h1>www.itcast.cn</h1></html>

#coding=utf-8import reret = re.match(r"<(\w*)><(\w*)>.*</\2></\1>", "<html><h1>www.itcast.cn</h1></html>") #\2对应第二个(\w*)   \1对应第一个(\w*)ret.group()#结果:<html><h1>www.itcast.cn</h1></html>ret = re.match(r"<(\w*)><(\w*)>.*</\2></\1>", "<html><h1>www.itcast.cn</h2></html>")ret.group()#AttributeError: 'NoneType' object has no attribute 'group'

示例5:(?P<name>) (?P=name)

(?P<name>):设置组的别名

(?P=name):获取组名

需求:匹配出<html><h1>www.itcast.cn</h1></html>

#coding=utf-8import reret = re.match(r"<(?P<name1>\w*)><(?P<name2>\w*)>.*</(?P=name2)></(?P=name1)>", "<html><h1>www.itcast.cn</h1></html>")ret.group()ret = re.match(r"<(?P<name1>\w*)><(?P<name2>\w*)>.*</(?P=name2)></(?P=name1)>", "<html><h1>www.itcast.cn</h2></html>")ret.group()

注意:(?P<name>)(?P=name)中的字母p大写

运行结果:





原创粉丝点击