正则表达式(regular expression)描述了一种字符串匹配的模式(pattern),可以用来检查一个串是否含有某种子串、将匹配的子串替换或者从某个串中取出符合某个条件的子串等。对于爬取网页和文本处理都非常有用。
match()
match() 方法会尝试从字符串的起始位置开始匹配正则表达式,如果匹配就返回匹配成功的结果,如果一旦从开头就不匹配则返回None
import re
content="Hello 123 4567 World_This is a Regex Demo"
print(len(content))
# match()第一个参数传入正则表达式,第二个餐数传入要匹配的字符串
result=re.match('^Hello\s\d\d\d\s\d{4}\s\w{10}',content)
print(result) # 打印输出结果是SRE_Match对象
print(result.group()) # 打印匹配内容
print(result.span()) # 输出匹配的范围
41
<_sre.SRE_Match object; span=(0, 25), match='Hello 123 4567 World_This'>
Hello 123 4567 World_This
(0, 25)
匹配目标
可以使用()将想要匹配的子字符串括起来,被标记的每个子表达式会依次对应每一个分组,调用group()方法传入分组索引即可。
import re
content='Hello 1234567 World_This is a Regex Demo'
result=re.match('^Hello\s(\d+)\sWorld',content)
print(result)
print(result.group()) # group()中为空或为0输出完整结果
print(result.group(1))
print(result.span())
<_sre.SRE_Match object; span=(0, 19), match='Hello 1234567 World'>
Hello 1234567 World
1234567
(0, 19)
通用匹配
利用 .* 来匹配除了含有\n外的任意字符串。
import re
content="Hello 123 4567 World_This is a Regex Demo"
result=re.match("^Hello.*Demo$",content)
print(result)
print(result.group())
print(result.span())
<_sre.SRE_Match object; span=(0, 41), match='Hello 123 4567 World_This is a Regex Demo'>
Hello 123 4567 World_This is a Regex Demo
(0, 41)
贪婪与非贪婪
默认是贪婪匹配,贪婪匹配会使.*匹配尽量多的字符串。我们可以使用非贪婪匹配来解决这个问题,在在匹配式后面加?
import re
content="Hello 1234567 World_This is a Regex Demo"
result_1=re.match('^Hello.*(\d+).*Demo$',content)
result_2=re.match('^Hello.*?(\d+).*Demo$',content)
print(result_1)
print(result_1.group(1))
print(result_2)
print(result_2.group(1))
<_sre.SRE_Match object; span=(0, 40), match='Hello 1234567 World_This is a Regex Demo'>
7
<_sre.SRE_Match object; span=(0, 40), match='Hello 1234567 World_This is a Regex Demo'>
1234567
但如果在要匹配的结果后面加?可能什么也匹配不到
import re
content='http://weibo.com/comment/kEraCN'
result1=re.match('http.*?comment/(.*?)',content)
result2=re.match('http.*?comment/(.*)',content)
print('result1:',result1.group(1))
print('result2:',result2.group(1))
result1:
result2: kEraCN
修饰符
正则表达式中可以包含一些可选标志修饰符来控制匹配模式。修饰符被指定为一个可选的标志。
import re
content='''Hello 1234567 World_This
is a Regex Demo'''
# re.S修饰符的作用是匹配包括换行福符在内的所有内容
result=re.match("^H.*?(\d+).*?Demo$",content,re.S)
print(result.group(1))
1234567
常用修饰符:
re.I:使匹配大小写不敏感
re.L:做本地识别化匹配
re.M:多行匹配,影响^和$
re.S:使.匹配包括换号符在内的所有字符
re.U:根据Unicode字符集解析字符。这个标志影响\w,\W,\b和\B
re.X:该标志通过给予你更灵活的格式以便你将正则表达式写得更易于理解
转义匹配
用于匹配正则表达式的特殊符号,使用 \ 进行转义匹配
import re
content='(百度)www.baidu.com'
result=re.match('\(百度\)www\.baidu\.com',content)
print(result)
print(result.group())
<_sre.SRE_Match object; span=(0, 17), match='(百度)www.baidu.com'>
(百度)www.baidu.com
search()
匹配时扫描整个字符串,然后返回第一个匹配成功的结果。
import re
content="Hello taoist 1234567 World_This is a Regex Demo"
result=re.search('taoist.*?(\d+).*',content)
print(result)
print(result.group(1))
# 如果是match()方法则不会匹配到字符串
<_sre.SRE_Match object; span=(6, 47), match='taoist 1234567 World_This is a Regex Demo'>
1234567
findall()
findall()方法会遍历整个字符串,返回所有正则表达式匹配到的结果
import re
content="abcd1234efgh5678"
result=re.findall('[a-z]+(\d+)',content)
print(result[0])
print(result[1])
1234
5678
sub()
除了用正则表达式处理信息外,还用于修改文本。第一个参数传入正则表达式,第二个参数传入要进行替换的字符串,第三个参数传入要进行匹配的字符串。
import re
content="54aKS4yrsoiRS4ixSL2g"
result=re.sub('\d+','',content)
print(result)
aKSyrsoiRSixSLg
compile()
可以将郑泽字符串编译成正则表达式对象,以便后面的匹配中反复使用。
import re
content1='2016-12-15 12:00'
content2 ='2016-12-17 12:55'
content3 ='2016-12-22 13:21'
pattern=re.compile('\d{2}:\d{2}')
result1=re.sub(pattern,'',content1)
result2=re.sub(pattern,'',content2)
result3=re.sub(pattern,'',content3)
print(result1,result2,result3)
2016-12-15 2016-12-17 2016-12-22
参考:崔庆才《python3网络爬虫开发实战》