常用匹配规则
match()方法尝试从字符串的起始位置匹配正则表达式。如果匹配,则返回匹配成功的结果,否则返回None。
import re
content = 'Hello 123 4567 World_This is a Regex Demo'
# 第一个参数为匹配规则,第二个参数为将要匹配的字符串
result = re.match('^Hello\s\d\d\d\s\d{4}\s\w{10}', content)
print(result)
# 返回匹配内容
print(result.group())
# 返回匹配范围
print(result.span())
<_sre.SRE_Match object; span=(0, 25), match='Hello 123 4567 World_This'> Hello 123 4567 World_This (0, 25)
^Hello\s\d\d\d\s\d{4}\s\w{10}
^为匹配字符串开头,加上Hello就是匹配以Hello字符串开头的字符
\s:匹配空白字符,这里匹配空格
\d:匹配数字,一个\d只匹配一个数字,连续三个\d匹配了三个数字
\d{4}: 作用与\d\d\d\d相同,则为匹配4个数字
\w: 匹配字母,数字,下划线
从match()方法匹配到的字符串中,提取其中一部分内容。这里可以使用(),()标记了一个子表达式的开始和结束为止,被()标记的子表达式会依次对应一个分组,使用group分组的索引即可提取。
import re
content = 'Hello 1234567 324 World_This is a Regex Demo'
# 此处+为匹配一个或多个表达式
result = re.match('^Hello\s(\d+)\s(\d+)\sWorld', content)
print(result)
print('result.group():', result.group())
print('result.group(1):', result.group(1))
print('result.group(2):', result.group(2))
print(result.span())
<_sre.SRE_Match object; span=(0, 23), match='Hello 1234567 324 World'> result.group(): Hello 1234567 324 World result.group(1): 1234567 result.group(2): 324 (0, 23)
使用.可以匹配任意字符(除了换行符), *代表匹配前面的字符无限次。
import re
content = 'Hello 123 4567 World_This is a Regex Demo'
# $为以某个字符串结尾,这里为以Demo字符串结尾
result = re.match('^Hello.*Demo$', content)
print(result)
print(result.group())
<_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
import re
content = 'Hello 1234567 World_This is a Regex Demo'
result = re.match('^Hello.*(\d+).*Demo$', content)
print(result.group())
print(result.group(1))
Hello 1234567 World_This is a Regex Demo 7
本来我们想匹配1234567,而这里却只匹配到了7。在使用.的时候,会出现贪婪与非贪婪匹配的问题。.会尽可能匹配多的字符,而\d+匹配至少一个字符,所以最后的结果\d+只匹配了一个字符7,而.*则把前面的123456全都匹配。这里使用.*?则为非贪婪的模式。
import re
content = 'Hello 1234567 World_This is a Regex Demo'
result = re.match('^Hello.*?(\d+).*Demo$', content)
print(result.group())
print(result.group(1))
Hello 1234567 World_This is a Regex Demo 1234567
正则表达式可以包含一些可选标志修饰符来控制匹配模式。
import re
content = '''Hello 1234567 World_This
is a Regex Demo
'''
result = re.match('^Hello.*?(\d+).*Demo$', content)
print(result.group(1))
--------------------------------------------------------------------------- AttributeError Traceback (most recent call last) <ipython-input-27-21790ec92c73> in <module> 5 ''' 6 result = re.match('^Hello.*?(\d+).*Demo$', content) ----> 7 print(result.group(1)) AttributeError: 'NoneType' object has no attribute 'group'
如果这样直接匹配会报错,因为字符串中出现了换行,.是不能匹配换行符的。智力需要一个修饰符re.S,使用该修饰符,可以让.匹配换行符在内的所有字符。
import re
content = '''Hello 1234567 World_This
is a Regex Demo
'''
result = re.match('^Hello.*?(\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.group())
(百度)www.baidu.com
match()方法是从字符串的开头匹配的,search()方法会扫描整个字符串,返回第一个匹配成功的结果,如果没有匹配到,则返回None。
import re
html = '''<div id="songs-list">
<h2 class="title">经典老歌</h2>
<p class="introduction">
经典老歌列表
</p>
<ul id="list" class="list-group">
<li data-view="2">一路有你</li>
<li data-view="7">
<a href="/2.mp3" singer="任贤齐">沧海一笑</a>
</li>
<li data-view="4" class="active">
<a href="/3.mp3" singer="齐秦">往事随风</a>
</li>
<li data-view="6"><a href="/4.mp3" singer="beyond">光辉岁月</a></li>
<li data-view="5"><a href="/5.mp3" singer="陈慧琳">记事本</a></li>
<li data-view="5">
<a hred="/6.mp3" singer="邓丽君">但愿人长久</a>
</li>
</ul>
</div>'''
# 获取class为activie的li节点的歌手名与歌名
result = re.search('<li.*?active.*?singer="(.*?)">(.*?)</a>', html, re.S)
print(result.group(1))
print(result.group(2))
齐秦 往事随风
search()是匹配第一个内容,而findall()则是返回所有匹配的内容。
import re
html = '''<div id="songs-list">
<h2 class="title">经典老歌</h2>
<p class="introduction">
经典老歌列表
</p>
<ul id="list" class="list-group">
<li data-view="2">一路有你</li>
<li data-view="7">
<a href="/2.mp3" singer="任贤齐">沧海一笑</a>
</li>
<li data-view="4" class="active">
<a href="/3.mp3" singer="齐秦">往事随风</a>
</li>
<li data-view="6"><a href="/4.mp3" singer="beyond">光辉岁月</a></li>
<li data-view="5"><a href="/5.mp3" singer="陈慧琳">记事本</a></li>
<li data-view="5">
<a hred="/6.mp3" singer="邓丽君">但愿人长久</a>
</li>
</ul>
</div>'''
# 获取所有的超链接,歌手名,歌名
results = re.findall('<li.*?href="(.*?)".*?singer="(.*?)">(.*?)</a>', html, re.S)
print(type(results))
print(results)
for result in results:
print(type(result))
print(result[0], result[1], result[2])
<class 'list'> [('/2.mp3', '任贤齐', '沧海一笑'), ('/3.mp3', '齐秦', '往事随风'), ('/4.mp3', 'beyond', '光辉岁月'), ('/5.mp3', '陈慧琳', '记事本')] <class 'tuple'> /2.mp3 任贤齐 沧海一笑 <class 'tuple'> /3.mp3 齐秦 往事随风 <class 'tuple'> /4.mp3 beyond 光辉岁月 <class 'tuple'> /5.mp3 陈慧琳 记事本
修改文本可使用replace(),也可以使用sub()。
import re
content = 'fdsa54343fddda34GSDGf34'
# 第一个参数为删除的规则,第二个为删除后,替换的规则,第三个为原字符串
content = re.sub('\d+', '', content)
print(content)
fdsafdddaGSDGf
import re
html = '''<div id="songs-list">
<h2 class="title">经典老歌</h2>
<p class="introduction">
经典老歌列表
</p>
<ul id="list" class="list-group">
<li data-view="2">一路有你</li>
<li data-view="7">
<a href="/2.mp3" singer="任贤齐">沧海一笑</a>
</li>
<li data-view="4" class="active">
<a href="/3.mp3" singer="齐秦">往事随风</a>
</li>
<li data-view="6"><a href="/4.mp3" singer="beyond">光辉岁月</a></li>
<li data-view="5"><a href="/5.mp3" singer="陈慧琳">记事本</a></li>
<li data-view="5">
<a hred="/6.mp3" singer="邓丽君">但愿人长久</a>
</li>
</ul>
</div>'''
# 在提取所有li节点中的歌名时,可以先把<a>节点删去,简化结构。
# |为或
html = re.sub('<a.*?>|</a>', '', html)
print(html)
results = re.findall('<li.*?>(.*?)</li>', html, re.S)
for result in results:
# 删除字符开头或结尾的空白符或换行符
print(result.strip())
<div id="songs-list"> <h2 class="title">经典老歌</h2> <p class="introduction"> 经典老歌列表 </p> <ul id="list" class="list-group"> <li data-view="2">一路有你</li> <li data-view="7"> 沧海一笑 </li> <li data-view="4" class="active"> 往事随风 </li> <li data-view="6">光辉岁月</li> <li data-view="5">记事本</li> <li data-view="5"> 但愿人长久 </li> </ul> </div> 一路有你 沧海一笑 往事随风 光辉岁月 记事本 但愿人长久
将正则规则进行封装,即可重复使用。
import re
content1 = '2016-12-12 19:00'
content2 = '2016-11-13 12:20'
pattern = re.compile('\d{2}:\d{2}')
result1 = re.sub(pattern, '', content1)
result2 = re.sub(pattern, '', content2)
print(result1, result2)
2016-12-12 2016-11-13