正则表达式
常用的匹配规则
- \w 匹配字母、数字和下划线
- \s 匹配任意空白字符,等价于[\n \t \r \f]
- \d 匹配任意数字,等价于[0-9]
- ^ 匹配一行字符串的开头
- $ 匹配一行字符串的结尾
- . 匹配任意字符,除了换行符
- * 匹配前面的字符无限次
- + 匹配1个或多个表达式
- ? 匹配0个或1个前面的正则表达式定义的片段,非贪婪方式
- () 匹配括号里的表达式,也表示一个组
1.match()
match()方法会尝试从字符串的起始位置匹配正则表达式,如果匹配,就返回匹配成功的结果;如果失败,则返回None。
import re
content = 'chen jia qq number is 1041076885 Chenih'
result = re.match('^chen.*Chenih$', content)
print(result.group())
- 匹配目标
如果想从字符串中提取一部分内容,可使用()括号将想提取的子字符括起来。()实际上标记了一个子表达式的开始和结束位置,被标记的每个子表达式会依次对应每一个分组,调用group()方法传入分组的索引可以获得提取的结果。
import re
content = 'chen jia qq number is 1041076885 Chenih'
result = re.match('^chen\s\w{3}\s\w{2}\s\w{6}\s\w{2}\s(\d+)\s\w{6}', content)
print(result.group(1))
- 通用匹配
.*组合在一起可以匹配任意字符。
import re
content = 'chen jia qq number is 1041076885 Chenih'
result = re.match('^chen.*Chenih$', content)
print(result.group())
- 贪婪与非贪婪
在贪婪匹配下,.*会尽可能匹配更多的字符。非贪婪匹配则是尽可能匹配更少的字符。写法为.*?
import re
content = 'chen jia qq number is 1041076885 Chenih'
result = re.match('^chen.*?(\d+)Chenih$', content)
# 这样匹配出来的则是1041076885,如若不加?则只会匹配出5
print(result.group(1))
要注意的是,如果匹配的是字符串结尾的字符,使用.*?就匹配不到任何内容。(它会尽可能少的匹配字符)
- 转义匹配
.匹配除了换行符外的所有字符,但是如果字符串里面包含的有.,那么就需要用到转义匹配。
import re
content = '(百度)www.baidu.com'
# 因为()和.都是用于正则匹配的特殊字符,所有在前面要加上\进行转义
result = re.match('\(百度\)www\.baidu\.com', content)
当遇到用于正则匹配模式的特殊字符时,在前面加反斜线转义即可。
修饰符
- re.I 使匹配对大小写不敏感
- re.S 使.匹配包括换行符在内的所有字符
- re.M 多行匹配,影响^和$
- re.L 做本地化识别(locale-aware)匹配
- re.U 根据Unicode字符集解析字符。这个标志影响\w、\W、\b和\B
- re.X 该标志通过给予你更灵活的格式以便你将正则表达式写得更易于理解
2.search()
search()方法会在匹配时扫描整个字符串,然后返回第一个成功匹配的结果。
import re
content = 'Hello 123 4567 World_This is a Regex Demo'
result = re.search('World.*?Demo', content)
print(result)
3.findall()
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 date-view="7">
<a href="/2.mp3" singer="任贤齐">沧海一声笑</a>
</li>
<li data-view="4" class="active">
<a href="/3.mp3" singer="齐秦">往事随风</a>
</li>
<li date-view="6"><a href="/4.mp3" singer="beyond">光辉岁月</a></li>
<li date-view="5"><a href="/5.mp3" singer="陈慧琳">记事本</a></li>
<li data-view="5">
<a href="/6.mp3" singer="邓丽君">但愿人长久</a>
</li>
</ul>
</div>
'''
# findall()方法会搜索所有符合这个正则表达式的字符串 re.S可以使.*?匹配换行符
results = re.findall('<li.*?href="(.*?)".*?singer="(.*?)">(.*?)</a>', html, re.S)
print(results)
for result in results:
print(result)
4.sub()
sub()方法可以用来修改文本。
import re
content = '54cjhmxcxqsgj19py99thon'
result = re.sub('\d+', '', content)
print(result)
5.compile()
compile()方法可以将正则字符串编译成正则表达式对象,以便在后面的匹配中复用。
compile()方法中也可以传入修饰符,这样在search()、findall()方法中就不用额外传入了。
import re
content1 = '2016-10-10 12:00'
content2 = '2012-12-1 12:55'
content3 = '1998-10-24 13:21'
# 这个正则表达式匹配内容为12:00这个一段,使用compile()将正则字符串编译成正则表达式对象
pattern = re.compile('\d{2}:\d{2}')
# 使用sub将上面的正则表达式对象去掉
result1 = re.sub(pattern, '', content1)
result2 = re.sub(pattern, '', content2)
result3 = re.sub(pattern, '', content3)
print(result1, result2, result3)