Python正则表达式学习

一、规则总结

1.正则表达式语法
    1.1. ?匹配0或1次前面的分组,上限是1
    1.2. * 匹配大于等于0次前面的分组,上限是无限
    1.3. + 匹配大于等于1次前面的分组,上限是无限
    1.4. {n}匹配n次前面的分组
    1.5. {n,}匹配大于等于n次前面的分组
    1.6. {,m}匹配小于等于m次前面的分组
    1.7. {n,m}匹配大于等于n次,小于等于m次前面的分组
    1.8. {n,m}?对前面的分组进行非贪心匹配
    1.9. *?对前面的分组进行非贪心匹配
    1.10. +?对前面的分组进行非贪心匹配
    1.11. ^spam 字符串必须以spam开始
    1.12. spam$ 字符串必须以spam结束
    1.13. 点号.匹配所有字符,除了换行符\n
    1.14. \d匹配数字,\D匹配数字以外的字符
    1.15. \w匹配字母,\W匹配字母以外的字符
    1.16. \s匹配空格,\S匹配空格以外的字符
    1.17. [abc]匹配方括号内的任意字符(例如:a,b,c)
    1.18. [^abc]匹配不在方括号内的任意字符
    1.19. | 匹配任意一个

    1.20.re.compile('foo', re.IGNORECASE) 加参数re.IGNORECASE表示匹配时忽略大小写

    1.21.re.compile('foo', re.DOTALL) 加参数re.DOTALL表示匹配时忽略换行或回车

    1.22.re.compile('foo', re.VERBOSE) 加参数re.VERBOSE表示匹配时忽略正则表达式里面的注释

注:为什么?表示0和1,因为问号就是问是否存在的意思,那回答肯定是存在1或不存在0.所以问号可以表示0和1个。--------自己想的助记方法

2.正则表达式在python代码里如何使用

    2.0.使用正则表达式前记得导入 re。 

import re


    2.1.re.rearch()正则表达式打括号说明有分组,需要按分组匹配。有分组的匹配结果值是数组,需要用groups()方法接收。
    2.2.re.rearch()正则表达式没有打括号,说明没有分组,需要按全字段匹配。没有分组的匹配结果是单个字符串,需要用group()方法接收。
    2.3.re.findall()可以找所有的匹配,且返回值是数组,且不需要group()接收
3.贪心匹配和非贪心匹配
    默认有歧义时,所有匹配都是贪心匹配。
    如果要非贪心匹配则要加?
4.匹配换行符

二、例子

1.或|的使用

heroRegex=re.compile(r'Batman|Tina Fey')
mo1=heroRegex.search('Batman and Tina Fey Batman')
print(mo1.group())

# 执行结果:
# Batman

 2.或|的使用

heroRegex=re.compile(r'Batman|Tina Fey')
mo1=heroRegex.search('Watman and Tina Fey Batman')
print(mo1.group())

# 执行结果
# Tina Fey

3.或|的使用,且带了分组

batRegex=re.compile(r'Bat(man|mobile|copter|bat)')
mo1=batRegex.search('Batcopter lost a Batbat')
print(mo1.group())

# 执行结果
# Batcopte

4.或|的使用,且带了分组

batRegex=re.compile(r'Bat(man|mobile|copter|bat)')
mo1=batRegex.search('Batmanmobile lost a Batbat')
print(mo1.group())
# 执行结果
# Batman

5.或|的使用,且带了分组,只取分组里获取的内容

batRegex=re.compile(r'Bat(man|mobile|copter|bat)')
mo1=batRegex.search('Batmanmobile lost a Batbat')
print(mo1.group(1))
# 执行结果
# man

6. ?精确匹配0个或1个。超过1个就不能匹配了

batRegex=re.compile(r'Bat(wo)?man')
mo=batRegex.search('The Adventures of Batman')
print(mo.group())
mo2=batRegex.search('The Adventures of Batwoman')
print(mo2.group())
mo3=batRegex.search('The Adventures of Batwowoman')
print(mo3==None)

#执行结果
# Batman
# Batwoman
# True
phoneRegex=re.compile(r'(\d\d\d-)?\d\d\d-\d\d\d\d')
mo6=phoneRegex.search('My number is 415-555-4242')
print(mo6.group())
mo7=phoneRegex.search('My number is 999-4242')
print(mo7.group())

# 执行结果
# 415-555-4242
# 999-4242

7.*匹配0个到无数个

batRegex2=re.compile(r'Bat(wo)*man')
mo8=batRegex2.search('The Adventures of Batwowoman')
print(mo8.group())

# 执行结果
# Batwowoman
batRegex2=re.compile(r'Bat(wo)*man')
mo9=batRegex2.search('The Adventures of Batman')
print(mo9.group())
# Batman

8. +匹配1个到无数个

batRegex3=re.compile(r'Bat(wo)+man')
mo2=batRegex3.search('The Adventures of Batman')
print(mo2==None)
# True
batRegex3=re.compile(r'Bat(wo)+man')
mo3=batRegex3.search('The Adventures of Batwoman')
print(mo3.group())
# Batwoman
batRegex3=re.compile(r'Bat(wo)+man')
mo4=batRegex3.search('The Adventures of Batwowoman')
print(mo4.group())
# Batwowoman

9. {n,m}匹配n到m个,且左右都为闭区间。任意一个参数不写则默认为0

batRegex4=re.compile(r'Bat(wo){,2}man')
mo10=batRegex4.search('The Adventures of Batman')
print(mo10.group())
# Batman
batRegex4=re.compile(r'Bat(wo){,2}man')
mo10=batRegex4.search('The Adventures of Batwowoman')
print(mo10.group())
# Batwowoman
batRegex4=re.compile(r'Bat(wo){,2}man')
mo10=batRegex4.search('The Adventures of Batwowowoman')
print(mo10==None)
# True

10. ?非贪心匹配

按最少去匹配

batRegex5=re.compile(r'(wo){2,4}?')
mo11=batRegex5.search('The Adventures of wowowowo')
print(mo11.group())
# wowo

与下面的贪心匹配对比

按最多去做匹配

batRegex5=re.compile(r'(wo){2,4}')
mo11=batRegex5.search('The Adventures of wowowowo')
print(mo11.group())
# wowowowo

11.注意与非贪心匹配区别

虽然此处用了非贪心匹配,但是结果和贪心匹配的结果一样

batRegex6=re.compile(r'Bat(wo){1,4}?man')
mo12=batRegex6.search('The Adventures of Batwowoman')
print(mo12.group())
#Batwowoman

 以下用的贪心匹配

batRegex6=re.compile(r'Bat(wo){1,4}man')
mo12=batRegex6.search('The Adventures of Batwowoman')
print(mo12.group())
# Batwowoman

12.search找的是第一个,返回值为字符串。findall可以找全部,返回值为数组

batRegex8=re.compile(r'\d\d\d-\d\d\d-\d\d\d\d') # 没有分组
mo14=batRegex8.search('Cell:415-555-9999 Work:222-555-0000')
print(mo14.group())
# 415-555-9999
batRegex8=re.compile(r'\d\d\d-\d\d\d-\d\d\d\d') # 没有分组
mo14=batRegex8.findall('Cell:415-555-9999 Work:222-555-0000')
print(mo14)
# ['415-555-9999', '222-555-0000']

以下这个有点不理解为什么不提取短横线 -

batRegex71=re.compile(r'(\d\d\d)-(\d\d\d)-(\d\d\d\d)') # 
mo131=batRegex71.findall('Cell:415-555-9999 Work:222-555-0000')
print(mo131)
# [('415', '555', '9999'), ('222', '555', '0000')]

13.findall使用

提取字符:提取1到无数个数字加空格加1到无数个字母

batRegex14=re.compile(r'\d+\s\w+') 
mo15=batRegex14.findall('12 drmmers,11 pipers,10 lords,9 ladies,8 maids,7 swans,6 geese')
print(mo15)
# ['12 drmmers', '11 pipers', '10 lords', '9 ladies', '8 maids', '7 swans', '6 geese']

14.findall使用

batRegex15=re.compile(r'[aeiouAEIOU]') 
mo16=batRegex15.findall('RoboCop eats baby food. BABY FOOD.')
print(mo16)
# ['o', 'o', 'o', 'e', 'a', 'a', 'o', 'o', 'A', 'O', 'O']

15.findall使用

暂时对此正则表达式有疑问

^作用的是0-5 还是后面的表达式都作用了呢?

batRegex17=re.compile(r'[^0-5A-Za-z.\s]') 
mo18=batRegex17.findall('3RoboCop 4 eats 6baby 1food. 8BABY FOOD.')
print(mo18)
# ['6', '8']

16.findall使用

atRegex = re.compile(r'.at')
mo22=atRegex.findall('The cat in the hat sat on the flat mat.')
print(mo22)
# ['cat', 'hat', 'sat', 'lat', 'mat']

17.search使用

nameRegex = re.compile(r'First Name: (.*) Last Name: (.*)')
mo23 = nameRegex.search('First Name: Al Last Name: Sweigart')
print(mo23.group())
print(mo23.group(1))
print(mo23.group(2))
# First Name: Al Last Name: Sweigart
# Al
# Sweigart

18.贪心匹配和非贪心匹配例子再来一个

非贪心

nongreedyRegex = re.compile(r'<.*?>')
mo24 = nongreedyRegex.search('<To serve man> for dinner.>')
print(mo24.group())
# <To serve man>

贪心 

nongreedyRegex = re.compile(r'<.*>')
mo24 = nongreedyRegex.search('<To serve man> for dinner.>')
print(mo24.group())
# <To serve man> for dinner.>

19. .*匹配除了换行符以外所有内容

noNewlineRegex = re.compile('.*')
mo26=noNewlineRegex.search('Serve the public trust.\nProtect the innocent.\nUphold the law.')
print(mo26.group())
# 执行结果
#  Serve the public trust.



#\n表示折行
print('Serve the public trust.\nProtect the innocent.\nUphold the law.')
# 执行结果
#  Serve the public trust.
#  Protect the innocent.
#  Uphold the law.

20.加上参数 re.DOTALL 匹配换行符

newlineRegex = re.compile('.*', re.DOTALL)
mo27=newlineRegex.search('Serve the public trust.\nProtect the innocent.\nUphold the law.')
print(mo27.group())
# Serve the public trust.
# Protect the innocent.
# Uphold the law.

21.匹配时忽略字母大小写

batRegex18=re.compile(r'good',re.IGNORECASE) 
mo=batRegex18.search('Hello GOOD world')
print(mo.group())
#GOOD
batRegex18=re.compile(r'good',re.I) 
mo=batRegex18.search('Hello GOOD world')
print(mo.group())
#GOOD

22.正则表达式匹配并替换

namesRegex = re.compile(r'Agent \w+')
mo=namesRegex.sub('CENSORED', 'Agent Alice gave the secret documents to Agent Bob ,great Agent .')
print(mo)
#'CENSORED gave the secret documents to CENSORED ,great CENSORED.'

22.正则表达式匹配并替换,按分组内的内容替换

agentNamesRegex = re.compile(r'Agent (\w)(\w)\w*')
mo=agentNamesRegex.sub(r'\1****','Agent Alice told Agent Carol that Agent Eve knew Agent Bob was a double agent.')
print(mo)
#A**** told C**** that E**** knew B**** was a double agent.

 注意:

1.替换的字符也是来自正则表达式 

2.替换的字符里1和2代表的是取分组,上面的正则表达式正好有两个括号对应的是两个分组。

agentNamesRegex = re.compile(r'Agent (\w)(\w)\w*')
mo=agentNamesRegex.sub(r'\2****','Agent Alice told Agent Carol that Agent Eve knew Agent Bob was a double agent.')
print(mo)
#l**** told a**** that v**** knew o**** was a double agent.

23.复杂正则表达式的书写

使用re.VERBOSE参数,让正则表达式忽略空格、注释。

目的:便于书写复杂的正则表达式,可以给每个小段正则表达式换行和加注释

phoneRegex = re.compile(r'''(
(\d{3}|\(\d{3}\))? 			 # area code
(\s|-|\.)? 					 # separator
\d{3} 						 # first 3 digits
(\s|-|\.) 					 # separator
\d{4} 						 # last 4 digits
(\s*(ext|x|ext.)\s*\d{2,5})? # extension	
)''', re.VERBOSE)

其中三重引号(''')代表的是多行字符串

24.正则表达式既要匹配换行 re.DOTALL、又要忽略大小写re.IGNORECASE 、又要编写注释re.VERBOSE

someRegexValue = re.compile('foo', re.IGNORECASE | re.DOTALL | re.VERBOSE)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值