一、测试站点:正则表达式在线工具
二、语法
注:字符串前加r,或使用双反斜杠\实现对转义字符取消转义
模式 | 描述 |
---|---|
^ | 指定匹配字符串的开头 |
$ | 指定匹配字符串的末尾 例:*HelloDemo$指定模式串以"Hello"为首,"Demo"为尾 |
\w | 匹配一个字母/数字/下划线/汉字 |
\W | 匹配一个非字母/数字/下划线/汉字 |
\s | 匹配一个任意空白字符,等价于 [\t\n\r\f]. |
\S | 匹配一个任意非空字符 |
\d | 匹配一个任意数字,等价于 [0-9]. |
\D | 匹配一个任意非数字 |
. | 匹配任意字符,除了换行符,当re.DOTALL标记被指定时,则可以匹配包括换行符的任意字符。 |
* | 匹配0个或多个的表达式(有就匹配,没有拉倒) 例:.*匹配0或多个任意字符 |
+ | 匹配1个或多个的表达式。注意:若存在语法指定字符,则至少匹配到一个 |
? | 匹配0个或1个由前面的正则表达式定义的片段,非贪婪方式 |
() | 1、将括号内的正则表达式作为一个组 2、该组作为匹配目标 |
\1…\9 | 匹配第n个分组,即括号中的匹配目标的内容。 |
| | 指定匹配字符串的开头 |
参数re.S | 使 . 匹配包括换行在内的所有字符,即可视为DOTALL |
参数re.l | 匹配过程对大小写不敏感 |
[…] | 用来表示一组字符,单独列出:[amk] 匹配 ‘a’,‘m’或’k’ |
[^…] | 不在[]中的字符:[^abc] 匹配除了a,b,c之外的字符。 |
re{ n} | 精确匹配 n 个前面表达式。例如, o{2} 不能匹配 “Bob” 中的 “o”,但是能匹配 “food” 中的两个 o。 |
re{ n,} | 匹配 n 个前面表达式。例如, o{2,} 不能匹配"Bob"中的"o", |
re{ n, m} | 匹配 n 到 m 次由前面的正则表达式定义的片段,贪婪方式 |
a | b |
(?imx) | 正则表达式包含三种可选标志:i, m, 或 x 。只影响括号中的区域。 |
(?-imx) | 正则表达式关闭 i, m, 或 x 可选标志。只影响括号中的区域。 |
(?: re) | 类似 (…), 但是不表示一个组 |
(?imx: re) | 在括号中使用i, m, 或 x 可选标志 |
(?-imx: re) | 在括号中不使用i, m, 或 x 可选标志 |
(?#…) | 注释. |
(?= re) | 前向肯定界定符。如果所含正则表达式,以 … 表示,在当前位置成功匹配时成功,否则失败。但一旦所含表达式已经尝试,匹配引擎根本没有提高;模式的剩余部分还要尝试界定符的右边。 |
(?! re) | 前向否定界定符。与肯定界定符相反;当所含表达式不能在字符串当前位置匹配时成功 |
(?> re) | 匹配的独立模式,省去回溯。 |
\A | 匹配字符串开始 |
\Z | 匹配字符串结束,如果是存在换行,只匹配到换行前的结束字符串。 |
\z | 匹配字符串结束 |
\G | 匹配最后匹配完成的位置。 |
\b | 匹配一个单词边界,也就是指单词和空格间的位置。例如, ‘er\b’ 可以匹配"never" 中的 ‘er’,但不能匹配 “verb” 中的 ‘er’。 |
\B | 匹配非单词边界。‘er\B’ 能匹配 “verb” 中的 ‘er’,但不能匹配 “never” 中的 ‘er’。 |
\n, \t, 等. | 匹配一个换行符。匹配一个制表符。等 |
\10 | 匹配第n个分组的内容,如果它经匹配。否则指的是八进制字符码的表达式。 |
三、re库
1、re.match
优先使用.*?非贪婪范匹配,使用()捕捉匹配目标
(1)re.match(pattern, content, flags = 0)从字符串首开始匹配。
(2)匹配成功时
re.match()返回匹配对象
re.match().group()为匹配结果串
re.match().group(i)返回匹配结果串中 语法里第i个()中的内容
re.match().span()为匹配结果串下标域
例1:常规匹配
import re
"""
从头开始匹配内容为"Hello 123 4567 World_This is a Regex Demo"的字符串
"""
content = "Hello 123 4567 World_This is a Regex Demo"
result = re.match("^Hello\s\d{3}\s\d{4}\s\w{10}\s\w{2}\s\w\s\w{5}\sDemo$", content)
if result != None:
print(result)# <re.Match object; span=(0, 41), match='Hello 123 4567 World_This is a Regex Demo'>
print(result.group())# Hello 123 4567 World_This is a Regex Demo
print(result.span())# (0, 41)
else:
print("Fail to match!")
例2:范匹配
import re
"""
从头开始匹配以"Hello"开头、"Demo"结尾的字符串
"""
content = "Hello 123 4567 World_This is a Regex Demo"
result = re.match("^Hello.*Demo$", content)
if result != None:
print(result)# <re.Match object; span=(0, 41), match='Hello 123 4567 World_This is a Regex Demo'>
print(result.group())# Hello 123 4567 World_This is a Regex Demo
print(result.span())# (0, 41)
else:
print("Fail to match!")
例3:匹配目标
import re
"""
从头开始匹配以"Hello"开头、"Demo"结尾的字符串中第一个内容为"1234567"的子串
"""
content = "Hello 123 4567 World_This is a Regex Demo"
result = re.match("^Hello\s(\d*).*Demo$", content)
if result != None:
print(result)
print(result.group(1))
print(result.span())
else:
print("Fail to match!")
例4:贪婪&非贪婪匹配:匹配尽可能多的语法指定字符
import re
content = "Hello 123 4567 World_This is a Regexo Demo"
result = re.match("^He.*?(\d+).*(\d+).*Demo$", content)
print(result.group())
print(result.group(1))# .*?非贪婪方式,补货整块数字123
print(result.group(2))# .*贪婪房是,4567中仅捕获到7
例5:模式串中含正则表达式语法中的字符,在左添加转义字符’'消歧
import re
content = "Price is $5.00"
result = re.match("Price is $5.00", content)
print(result)
result = re.match("Price is \$5\.00", content)
print(result)
2、re.search()
(1)扫描整个字符串,返回第一个成功的匹配
import re
content = "Extra strings Hello 123 4567 World_This is a Regex Demo Extra strings"
result = re.search("Hello.*?(\d+\s\d+).*Demo", content)
print(result)
print(result.group(1))# 123 4567
3、re.findall(pattern, content, flag = 0)
返回content中所有符合正则表达式的结果,为一个元组列表,元组中是正则表达式中括号内的内容
例1:提取html中所有歌手-歌名: 超链接
import re
class Song():
def __init__(self, href, singer, name):
if len(href) != 0:
self.href = href
else:
self.href = "NULL"
if len(singer) != 0:
self.singer = singer
else:
self.singer = "NULL"
if len(name) != 0:
self.name = name
else:
self.name = "NULL"
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>'''
musics = []
results = re.findall('<li.*?>\s*?(<a href="(.*?)" singer="(.*?)">)?(\w*?)(</a>)?\s*?</li>', html)
for result in results:
musics.append( Song( href = result[1], singer = result[2], name = result[3] ) )
for song in musics:
print(song.singer + "-" + song.name + ": " + song.href)
'''
NULL-一路上有你: NULL
任贤齐-沧海一声笑: /2.mp3
齐秦-往事随风: /3.mp3
beyond-光辉岁月: /4.mp3
陈慧琳-记事本: /5.mp3
邓丽君-但愿人长久: /6.mp3
'''
4、re.sub(pattern, repl, content, count = 0, flags = 0)
repl为用于替换的字符串,也可为函数
count为最大替换次数
re.sub()返回content中符合正则表达式的部分被repl替换后的字符串。
例1:将所有数字转换为|NUM|
import re
content = "Extra strings Hello 4567 World_1This is2 a R3egex 1122 Demo Extra strings "
repl = "|NUM|"
result = re.sub("\d+", repl, content, 10)
print(result)
'''
Extra strings Hello |NUM| World_|NUM|This is|NUM| a R|NUM|egex |NUM| Demo Extra strings
'''
例2:将所有数字替换为|original number:原数字|
import re
content = "first number:123, second number:456_789, third number:101112"
result = re.sub("(\d+)", r"|original number:\1 |", content, count = 4)
print(result)
'''
first number:|original number:123 |, second number:|original number:456 |_|original number:789 |, third number:|original number:101112 |
'''
例3:删除无关字符,匹配所有汉字
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.sub('<.*?>', '', html, count = 1000)
print(result)
songs = re.findall('\s*(\w*)\s', result, re.S)
for song in songs:
print(song)
'''
经典老歌
经典老歌列表
一路上有你
沧海一声笑
往事随风
光辉岁月
记事本
但愿人长久
经典老歌
经典老歌列表
一路上有你
沧海一声笑
往事随风
光辉岁月
记事本
但愿人长久
'''
5、re.compile(pattern, flags = 0)
将正则表达式的样式编译为一个 正则表达式对象 (正则对象),可以使用re的匹配方法进行匹配匹配
prog = re.compile(pattern)
result = prog.match(string)
#等价于
result = re.match(pattern, string)
例1:提取所有单词,数字,汉字
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>'''
pattern = re.compile('\W+(\w*)\W+')
words = pattern.findall(html)
for word in words:
print(word, end = "、")
'''
div、songs、h2、title、h2、class、经典老歌列表、ul、list、list、li、view、一路上有你、li、view、a、2、singer、沧海一声笑、li、data、4、active、href、mp3、齐秦、a、li、view、a、4、singer、光辉岁月、li、data、5、href、mp3、陈慧琳、a、li、view、a、6、singer、但愿人长久、li、div、
'''