python第11天(1)

正则表达式

正则表达式是一种匹配模式,描述要匹配的一些字符串

匹配规则

1.单个:
. 除\n外所有字符
\d 数字,等同于[0-9]
\D 和\d相反,等同于[^0-9]
\s 匹配空白字符\t\n\r\f\v
\S 和\s相反,等于[^\t\n\r\f\v]
\w 数字字母,等于[a-zA-Z0-9]
\W非数字字母[^a-zA-Z0-9]

2.批量备选 | 如yes|no,表示他们选一个就可以

3.l量词(关于重复):
? 0或1次

  • 0或多次
    +1或多次
    特定:{m,n} 表示m到n此
    {n}表示n次
    {n,}和{,m}分别表示至少n次和至多m次

4.匹配模式
贪婪模式(默认):匹配尽量大范围的结果
非贪婪模式:匹配尽量小范围的结果,方法:在量词后面加 ?

5.边界匹配
^行首 $行尾 \b单词边界 \B非单词边界 \A输入开头 \Z输入结尾
这些可能因上下文差异有不同表现

python中的正则表达式

re模块
其用法,这里有一个基本的例子:

In[2]: import re
In[3]: text='Mike is 25.Tom is 8.'
In[4]: pattern=re.compile('\d+')
In[5]: ###编译匹配模式
In[6]: pattern.findall(text)      #找到所有符合pattern的模式
Out[6]: ['25', '8']
In[7]: re.findall('\d+',text)  #不想编译时可以这样写
Out[7]: ['25', '8']

编译后的模式对象为RegexObject对象,会将模式编译为字节码并缓存
编译时的一个小细节

In[23]: s='\\author'
In[24]: pattern=re.compile('\\author')  #编译后是\author,会把\a当成匹配规则,所以不对
In[25]: pattern.findall(s)
Out[25]: []
In[32]: pattern2=re.compile('\\\\author')
In[33]: pattern2.findall(s)
Out[33]: ['\\author']

findall()是查找所有非重叠匹配项,返回list

In[2]: text='Tom is 8.Mike is 9.Tim is10.'
In[3]: import re
pattern=re.compile(r'[A-Z]\w+')     #查找名字,因为所有名字都是大写,所以可以这样
In[7]: pattern.findall(text)
Out[7]: ['Tom', 'Mike', 'Tim']

常用的一些函数
.match(string,[,pos,[,endpos]])
不指定位置时匹配仅从开头开始,返回一个Match对象
.match(string,[,pos,[,endpos]])
不指定位置时任意位置搜索,返回一个Match对象
.finditer()
查找所有匹配项返回一个可迭代的match对象

matchobject

例子

In[2]: text='Tom is 8.Mike is 10.'
In[3]: import re
In[10]: text
Out[10]: 'Tom is 8.Mike is 10.'
In[11]: p1=re.compile(r'(\d+).*(\d+)')   #贪婪模式匹配
In[13]: p1.findall(text)
Out[13]: [('8', '0')]
In[14]: p1=re.compile(r'(\d+).*?(\d+)')   #非贪婪模式匹配
In[15]: p1.findall(text)
Out[15]: [('8', '10')]
In[16]: m=p1.search(text)
In[17]: m
Out[17]: <re.Match object; span=(7, 19), match='8.Mike is 10'>
In[18]: m.group()
Out[18]: '8.Mike is 10'
In[19]: m.group(0)
Out[19]: '8.Mike is 10'
In[20]: m.group(1)
Out[20]: '8'
In[21]: m.group(2)
Out[21]: '10'
In[22]: m.start(1)
Out[22]: 7
In[23]: m.start(2)
Out[23]: 17
In[24]: m.end(2)
Out[24]: 19

分别使用了贪婪和非贪婪模式匹配,这里重点是使用.search()方法返回的MatchObject对象,其中正则表达式的(\d+)中的括号是分组的意思,把他们分成了两组,使用MatchObject可以方便的查看包括分组的匹配结果,m.group(0|1|2)分别是所有结果,第一组的匹配结果,第二组的匹配结果,.start()和.end()分别代表每一组的开头和结束下标,其中.end()的返回结果下标不包括在里面
如果同时看分组的开始和结束下标,可以用.span()方法
.finditer()方法查找所有匹配项返回一个可迭代的match对象,例子:

In[25]: p1=re.compile(r'(\w+) (\w+)')
In[26]: text='She is more beautiful than me. '
In[27]: p1.findall(text)
Out[27]: [('She', 'is'), ('more', 'beautiful'), ('than', 'me')]
In[28]: it=p1.finditer(text)
In[29]: for m in it:
   ...:     print(m.group())
   ...:     
She is
more beautiful
than me

group编组

除上述的用法外,group编组还可以创建子正则以应用量词

In[30]: re.search(r'ab+c','ababc')
Out[30]: <re.Match object; span=(2, 5), match='abc'>
In[31]: re.search(r'(ab)+c','ababc')
Out[31]: <re.Match object; span=(0, 5), match='ababc'>

还可以限制备选项的范围

In[32]: re.search(r'center|re','center')
Out[32]: <re.Match object; span=(0, 6), match='center'>
In[33]: re.search(r'center|re','centre')
Out[33]: <re.Match object; span=(4, 6), match='re'>
In[34]: re.search(r'cent(er|re)','centre')
Out[34]: <re.Match object; span=(0, 6), match='centre'>
In[35]: re.search(r'cent(er|re)','center')
Out[35]: <re.Match object; span=(0, 6), match='center'>

还可以重用正则表达式中提取的内容

In[36]: re.search(r'(\w+) \1','hello world')
In[37]: re.search(r'(\w+) \1','hello hello world')
Out[37]: <re.Match object; span=(0, 11), match='hello hello'>
#必须\1和第一个分组的内容相同时才匹配,所以第一次没有结果

编组可以带名称,这是Python中的功能,格式是:?P<名称>模式

In[38]: text='Tom:98'
In[40]: p1=re.compile(r'(?P<name>\w+):(?P<score>\d+)')
In[41]: m=p1.search(text)
In[42]: m.group()
Out[42]: 'Tom:98'
In[43]: m.group(1)
Out[43]: 'Tom'
In[44]: m.group('name')  #根据分组名称查找
Out[44]: 'Tom'

综合应用

.split()分割字符串

In[2]: import re
In[3]: text='He is Tom.\nHe is Mike.\nShe is Alice.'
In[4]: p=re.compile(r'\n')
In[5]: p.split(text)
Out[5]: ['He is Tom.', 'He is Mike.', 'She is Alice.']
In[6]: re.split(r'\n',text)
Out[6]: ['He is Tom.', 'He is Mike.', 'She is Alice.']
In[7]: re.split(r'\W','Hello world')
Out[7]: ['Hello', 'world']
In[8]: re.split(r'-','Hello-world')
Out[8]: ['Hello', 'world']
In[9]: re.split(r'(-)','Hello-world')
#分组可以让结果包含分隔符
Out[9]: ['Hello', '-', 'world']
In[10]: re.split(r'\n',text,1)
#分割后除了第1个,剩下的所有作为一个整体,如果是2就是前两个,剩下作为一个整体
Out[10]: ['He is Tom.', 'He is Mike.\nShe is Alice.']

.sub()替换

In[14]: ords='abc000\nabc001\nabc002'
In[15]: re.sub(r'\d+','-',ords)
Out[15]: 'abc-\nabc-\nabc-'

更高级的例子
\g(数字)可以在替换中,选择之前的分组第x组如:

Out[16]: 'He is *better* than me.'
In[17]: re.sub(r'\*(.*?)\*','<strong></strong>',text)
Out[17]: 'He is <strong></strong> than me.'
In[18]: re.sub(r'\*(.*?)\*','<strong>\g(1)</strong>',text)
In[21]: re.sub(r'([a-z]+)(\d+)','\g<2>-\g<1>',ords)
Out[21]: '000-abc\n001-abc\n002-abc'
In[22]: re.subn(r'([a-z]+)(\d+)','\g<2>-\g<1>',ords)   #结果多一个数字,是替换的数量
Out[22]: ('000-abc\n001-abc\n002-abc', 3)

编译标记:
re.I 忽略大小写
re.M 匹配多行
re.S 指定".“匹配所有字符串,包括”\n"
等等,例如

In[26]: text='Python PYTHON python'
In[27]: re.findall('python',text)
Out[27]: ['python']
In[28]: re.findall('python',text,re.I)
Out[28]: ['Python', 'PYTHON', 'python']
In[29]: re.findall(r'^<html>','\n<html>')
Out[29]: []
In[30]: re.findall(r'^<html>','\n<html>',re.M)
Out[30]: ['<html>']
In[31]: re.findall(r'\d(.)','1\nabcd')
Out[31]: []
In[32]: re.findall(r'\d(.)','1\nabcd',re.S)
Out[32]: ['\n']

模块级别操作
re.purge()清理正则缓存,如编译过的正则就会被清除
re.escape()逃逸字符:忽略某些关键符号的含义,让他变成一个普通的字符

In[33]: re.findall('^','^abc^')
Out[33]: ['']
In[34]: re.findall(re.escape('^'),'^abc^')
Out[34]: ['^', '^']
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值