正则表达式是对字符串操作的一种逻辑公式,就是用事先定义好的一些特定字符、及这些特定字符的组合,组成一个规则字符串,这个“规则字符串”用来表达对字符串的一种过滤逻辑。
非python独有,使用re模块实现
最常规的匹配
\s表示 匹配任意空格,即任意空白字符\t\n\r\f
\d匹配任意数字{0-9}
\d{n}表示匹配n个数字
.表示匹配任意字符,除了换行符,除非指定re.S标记
匹配0个或多个表达式
.匹配任意除了换行符,除非re.S标记
^xxxx表示匹配字符的开头
xxxx$ 表示匹配字符串的结尾
? 匹配0个或者一个前面正则表达式定义的片段,非贪婪方式
import re
content = 'Hello 123 4567 World_This is a Regex Demo'
print(len(content))
result=re.match('^Hello\s\d\d\d\s\d{4}\s\w{10}.*Demo$',content)
print(result)
print(result.group())
print(result.span())
F:\anaconda\python.exe F:/py/3.py
41
<_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 123 4567 World_This is a Regex Demo'
result=re.match('^Hello.*Demo$',content)
print(result.group())
print(result.span())
F:\anaconda\python.exe F:/py/3.py
Hello 123 4567 World_This is a Regex Demo
(0, 41)
获取匹配目标
()表示括号内的表达式,也表示一个组
- 表示表示匹配一个或者多个表达式
import re
content = 'Hello 1234567 World_This is a Regex Demo'
result=re.match('^Hello\s(\d+)\sWorld.*Demo$',content) #
print(result.group(1)) #打印第一个小括号括起来的内容
print(result.group())
print(result.span())
F:\anaconda\python.exe F:/py/3.py
1234567
Hello 1234567 World_This is a Regex Demo
(0, 40)
贪婪匹配
import re
content = 'Hello 1234567 World_This is a Regex Demo'
resulta=re.match('^He.*(\d+).*Demo$',content) #.*一次进行匹配,尽可能匹配多的内容,所以匹配出是7
print(resulta)
print(resulta.group(1))
非贪婪匹配
import re
content = 'Hello 1234567 World_This is a Regex Demo'
resulta=re.match('^He.*?(\d+).*Demo$',content) #.*?匹配尽可能少的字符
print(resulta)
print(resulta.group(1))
匹配模式
import re #有换行符
content = """Hello 1234567 World_This
is a Regex Demo"""
resulta=re.match('^He.*?(\d+).*Demo$',content,re.S)
print(resulta.group(1))
F:\anaconda\python.exe F:/py/3.py
1234567
转义: 匹配特殊字符
import re
content = "price is $5.00"
result = re.match('price is \$5\.00',content)
print(result.group())
F:\anaconda\python.exe F:/py/3.py
price is $5.00
总结:尽量使用泛匹配、使用括号得到匹配目标,使用非贪婪模式,有换行就用re.Sre.S可以使得.可以匹配换行符
re.search 扫描整个字符串返回第一个成功的匹配
import re
content = 'EXtra strings Hello 1234567 World_This is a Rehex Demo EXTRA STINGS'
result = re.search('Hello.*?(\d+).*?Demo',content)
print(result.group(1))
F:\anaconda\python.exe F:/py/3.py
1234567
由于使用match方法需要限定头部和尾部,所以能用search方法就不用match方法!
re.findall search 是找寻一个结果的,而findall是找到所有结果的。
搜索字符串,以列表的形式返回全部能匹配的子串
可以使用for循环遍历这个列表进行输出
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 href="/6.mp3" singer="邓丽君"><i class="fa fa-user"></i>但愿人长久</a>
</li>
</ul>
</div>'''
result = re.search('<li.*?active.*?singer="(.*?)">(.*?)</a>', html, re.S)
if result:
print(result.group(1), result.group(2))
F:\anaconda\python.exe F:/py/3.py
齐秦 往事随风
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 href="/6.mp3" singer="邓丽君">但愿人长久</a>
</li>
</ul>
</div>'''
result = re.search('<li.*?singer="(.*?)">(.*?)</a>', html, re.S)
if result:
print(result.group(1), result.group(2))
F:\anaconda\python.exe F:/py/3.py
任贤齐 沧海一声笑
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 href="/6.mp3" singer="邓丽君">但愿人长久</a>
</li>
</ul>
</div>'''
result = re.search('<li.*?singer="(.*?)">(.*?)</a>', html)
if result:
print(result.group(1), result.group(2))
F:\anaconda\python.exe F:/py/3.py
beyond 光辉岁月
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 href="/6.mp3" singer="邓丽君">但愿人长久</a>
</li>
</ul>
</div>'''
results = re.findall('<li.*?href="(.*?)".*?singer="(.*?)">(.*?)</a>', html, re.S)
print(results)
print(type(results))
for result in results:
print(result)
print(result[0], result[1], result[2])
F:\anaconda\python.exe F:/py/3.py
[('/2.mp3', '任贤齐', '沧海一声笑'), ('/3.mp3', '齐秦', '往事随风'), ('/4.mp3', 'beyond', '光辉岁月'), ('/5.mp3', '陈慧琳', '记事本'), ('/6.mp3', '邓丽君', '但愿人长久')]
<class 'list'>
('/2.mp3', '任贤齐', '沧海一声笑')
/2.mp3 任贤齐 沧海一声笑
('/3.mp3', '齐秦', '往事随风')
/3.mp3 齐秦 往事随风
('/4.mp3', 'beyond', '光辉岁月')
/4.mp3 beyond 光辉岁月
('/5.mp3', '陈慧琳', '记事本')
/5.mp3 陈慧琳 记事本
('/6.mp3', '邓丽君', '但愿人长久')
/6.mp3 邓丽君 但愿人长久
这个例子需要仔细琢磨:小括号既能作为一个整体,也能表示一个分组
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 href="/6.mp3" singer="邓丽君">但愿人长久</a>
</li>
</ul>
</div>'''
results = re.findall('<li.*?>\s*?(<a.*?>)?(\w+)(</a>)?\s*?</li>', html, re.S)
print(results)
for result in results:
print(result[1])
F:\anaconda\python.exe F:/py/3.py
[('', '一路上有你', ''), ('<a href="/2.mp3" singer="任贤齐">', '沧海一声笑', '</a>'), ('<a href="/3.mp3" singer="齐秦">', '往事随风', '</a>'), ('<a href="/4.mp3" singer="beyond">', '光辉岁月', '</a>'), ('<a href="/5.mp3" singer="陈慧琳">', '记事本', '</a>'), ('<a href="/6.mp3" singer="邓丽君">', '但愿人长久', '</a>')]
一路上有你
沧海一声笑
往事随风
光辉岁月
记事本
但愿人长久
re.sub
替换字符串中每一个匹配的子串后,返回替换后的字符串
import re
content = 'Extra stings Hello 1234567 World_This is a Regex Demo Extra stings'
content = re.sub('\d+', '', content)
print(content)
F:\anaconda\python.exe F:/py/3.py
Extra stings Hello World_This is a Regex Demo Extra stings
import re
content = 'Extra stings Hello 1234567 World_This is a Regex Demo Extra stings'
content = re.sub('\d+', 'Replacement', content)
print(content)
F:\anaconda\python.exe F:/py/3.py
Extra stings Hello Replacement World_This is a Regex Demo Extra stings
import re
content = 'Extra stings Hello 1234567 World_This is a Regex Demo Extra stings'
content = re.sub('(\d+)', r'\1 8910', content)
print(content)
F:\anaconda\python.exe F:/py/3.py
Extra stings Hello 1234567 8910 World_This is a Regex Demo Extra stings
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 href="/6.mp3" singer="邓丽君">但愿人长久</a>
</li>
</ul>
</div>'''
html = re.sub('<a.*?>|</a>', '', html)
results = re.findall('<li.*?>(.*?)</li>', html, re.S)
print(results)
for result in results:
print(result.strip())
F:\anaconda\python.exe F:/py/3.py
['一路上有你', '\n 沧海一声笑\n ', '\n 往事随风\n ', '光辉岁月', '记事本', '\n 但愿人长久\n ']
一路上有你
沧海一声笑
往事随风
光辉岁月
记事本
但愿人长久
re.compile
将正则表达式编译成正则对象,以便于复用该匹配模式
注意返回的类型,并不是列表!
import re
content = '''Hello 1234567 World_This
is a Regex Demo'''
pattern = re.compile('Hello.*Demo', re.S)
result = re.match(pattern, content)
print(type(result))
print(result)