Python40_正则表达式

2019-09-28  本文已影响0人  jxvl假装

标准库模块

python3中使用re模块支持正则表达式(regular expression),需要定义一个用于邳的模式(pattern)字符串,以及一个要匹配的字符串(string)。

最简单的匹配:

import re

m = re.match("My", "My name is zhang3") #将两个参数进行匹配,其中,"My"是正则表达式模式,最简单的一种,只匹配字符My本身
#第二个参数为要匹配的字符串,re.match函数用于查看字符串是不是以正则表达式开头
#match是从字符串起始位置开始匹配,如果匹配成功,返回匹配结果(一个对象),否则返回None

print(m)    # m是一个对象

print(m.group())   #等价于m.grouop(0),输出"My"

print(m.start(),m.end())    #输出0 2,相匹配的开始位置和结束位置

print(m.span()) #输出(0,2),即相匹配的始终位置元组

如果要做大量的匹配和搜索,最好先编译正则表达式,然后再重复使用它

#需求:匹配电话号码

import re

tel_reg = "1[0-9]{10}"
r = re.match(tel_reg,"18323954188")
if r:
    print(r.group())
    print(r.span())
else:
    print("匹配失败...")

正则表达式中的通配符

# 匹配单个字符
.:匹配除换行符外的任意单个字节(可以在match时传入re.S来使.可以匹配换行符)
[]:匹配[]中列举的字符
\d:匹配数字字符,等价于[0-9],一位
\D:匹配非数字字符
\w:匹配包括下划线在内的任何字字符,类似与变量的命名,与[a-zA-Z0-9_]等价(相当于变量规范)
\W:匹配任何非字字符
\s:匹配任何空白,包括空格、制表、换页。等价于[\f\n\r\t\v]
\S:匹配任何非空白字符。等价于[^\f\n\r\t\v]

# 匹配多个字符
{n}:(对前面的一位字符)匹配n次(连着),n为非负整数
{n,}:(对前面的一位字符)至少匹配n次
{n,m}:(对前面的一位字符)至少匹配n次,至多匹配m次
*:匹配前一个字符0次或多次
+:匹配前一个字符一次或多次
?:匹配前一个字符0次或一次

\:对后面的有特殊意义的字符进行转义,使其能够正常输出,如:\.
^:匹配输入的开头,eg:reg = "^[0-9]",即要求必须以数字开头。但是如果其用于方括号内,则代表排除,eg:[^a-zA-Z],表示不能是字母
$:表示以...结束,eg:tel_reg = "1[0-9]{10}$",则要求以数字结尾

x|y:|表示或,x或者y,默认匹配最大范围,为了限定范围,可以加小括号(x|y)
():1. 起到范围的限定,如上所示;2. 分组,使括号里面的内容可以单独取出来;3. ()结合\num使用,num为要取的分组号,eg:r"<(\w+)>.*</\1>"中的\1就表示该处内容要与第一(此处仅一个)()中的内容一样
\num:如上所示,匹配第num个分组,来达到前后内容相同的效果
?P<group_name>:给分组起别名,eg:r"<(?P<p1>\w+)>(?P<p2>\w+)>.*</(?P=p2)></(?P=p1)>" # 第一个分组的名字为p1,其中要匹配的内容为\w+,第二个分组类似,第三个分组要匹配的内容必须与名字为p1的分组中的内容相一致
[xyz]:匹配括号内的任意一个字符,比如[abc]和plain中的a匹配
[^xyz]:匹配非括号内的任何字符
[a-z]:字符范围,和指定范围内的任一字符匹配,此处即表示所有小写字母
[^a-z]:否定字符范围,匹配不在指定范围内的任何字符

\b:匹配字符的边界。即:在字符可空格之间的位置,如:er\b和never中的er匹配,和verb中的er不匹配
\B:匹配非字符边界,一般来说,正则表达式中的大小写字母意义相反
\f:匹配换页字符
\n:匹配换行字符
\r:匹配回车字符
\t:匹配水平制表符
\v:匹配垂直制表符

应用练习:

小技巧:写正则表达式的匹配模式时,运用 r"xxx",从而减少\的使用

匹配手机号码:

import re

tel_reg = "^1[0-9]{10}$"
r = re.match(tel_reg,"18323954188aaa")
if r:
    print(r.group())
    print(r.span())
else:
    print("手机号码不合法")

因为没有以数字结尾,所以输出“手机号码不合法”

匹配邮箱:

import re

mail_reg = "[a-zA-Z0-9]{1,}@[a-zA-Z0-9]{1,}\.(com|cn|org|net)"
#注意,()有对正则表达式分组的功能

r = re.match(mail_reg,"2537119379@qq.com")
if r:
    print(r.group())    #相当于print(r.group(0))
    print(r.group(1))   #这里会输出com
else:
    print("邮箱名不合法")

利用通配符对正则表达式进行简化:

import re

mail_reg = "\w+@\w+\.(com|net|cn|org)"
tel_reg = "^1\d{10}$"

贪婪模式与非贪婪模式

content = "Hello 1234 world, this is a Demo regex"

reg = "^He.*(\d+).*regex$"  #贪婪模式,因为"."表示除换行符外的任意单个字符,
# *表示前一个字符的0次或多次,所以".*"能够匹配任意长的任意字符,尽可能长的匹配
#非贪婪模式:reg = "^He.*?(\d+).*regex$"  #注意,".*?"用在正则表达式末尾的时候,什么也匹配不上,因为是非贪婪模式,尽可能少的匹配
#贪婪模式即:尽可能匹配前面的。非贪婪模式即:一旦发现后面能够匹配上了,前面就不再匹配

修饰符

re.I:忽略大小写
re.S:使"."可以匹配换行符在内的任意字符

search方法

扫描整个字符串,返回第一个匹配结果

import re

content = "aaa121aad323ddd"
reg = "\d+" #匹配数字
r = re.search(reg, content)
if r:
    print(r.group())    #输出121
else:
    print("没有找到匹配内容...")

findall方法

返回字符串中所有不重叠匹配项的列表。如果模式中存在一个或多个捕获组,则返回组列表;如果模式有多个组,则返回元组的列表。

import re

content = "aaa121aad323ddd"
reg = "\d+" #匹配数字
r = re.findall(reg, content)
if r:
    print(r)    #注意,r为一个列表,而非search或match返回的对象
else:
    print("没有找到匹配内容...")

歌曲名查找

以下所用html内容来自于网易云音乐(用火狐浏览器):

  1. 进入网易云音乐官网,拉到有音乐排行榜处

  2. f12

  3. 在新出现的框中,用鼠标点击"查看器"前面的箭头

  4. 随便点击排行榜上的一首歌,会发现代码区有一行以蓝色标注出来,在其上方几行处,可看到"<ol>"

  5. 点击ol,然后右键->复制->整体HTML

import re

html = """
<ol>
<li onmouseover="this.className='z-hvr'" onmouseout="this.className=''" class="">
<span class="no no-top">1</span>
<a href="/song?id=1374483648" class="nm s-fc0 f-thide" title="Beautiful People (feat. Khalid)">Beautiful People (feat. Khalid)</a>
<div class="oper">
<a href="#" class="s-bg s-bg-11" title="播放" hidefocus="true" data-res-type="18" data-res-id="1374483648" data-res-action="play" data-res-from="31" data-res-data="19723756"></a>
<a href="#" class="u-icn u-icn-81" title="添加到播放列表" hidefocus="true" data-res-type="18" data-res-id="1374483648" data-res-action="addto" data-res-from="31" data-res-data="19723756"></a>
<a href="#" class="s-bg s-bg-12" title="收藏" hidefocus="true" data-res-level="0" data-res-fee="8" data-res-type="18" data-res-id="1374483648" data-res-action="subscribe"></a>
</div>
</li>
<li onmouseover="this.className='z-hvr'" onmouseout="this.className=''" class="">
<span class="no no-top">2</span>
<a href="/song?id=1374507779" class="nm s-fc0 f-thide" title="Heartbeat (BTS WORLD OST)">Heartbeat (BTS WORLD OST)</a>
<div class="oper">
<a href="#" class="s-bg s-bg-11" title="播放" hidefocus="true" data-res-type="18" data-res-id="1374507779" data-res-action="play" data-res-from="31" data-res-data="19723756"></a>
<a href="#" class="u-icn u-icn-81" title="添加到播放列表" hidefocus="true" data-res-type="18" data-res-id="1374507779" data-res-action="addto" data-res-from="31" data-res-data="19723756"></a>
<a href="#" class="s-bg s-bg-12" title="收藏" hidefocus="true" data-res-level="10" data-res-fee="4" data-res-type="18" data-res-id="1374507779" data-res-action="subscribe"></a>
</div>
</li>
<li onmouseover="this.className='z-hvr'" onmouseout="this.className=''" class="">
<span class="no no-top">3</span>
<a href="/song?id=1374446923" class="nm s-fc0 f-thide" title="I Fell In Love With The Devil (Radio Edit)">I Fell In Love With The Devil (Radio Edit)</a>
<div class="oper">
<a href="#" class="s-bg s-bg-11" title="播放" hidefocus="true" data-res-type="18" data-res-id="1374446923" data-res-action="play" data-res-from="31" data-res-data="19723756"></a>
<a href="#" class="u-icn u-icn-81" title="添加到播放列表" hidefocus="true" data-res-type="18" data-res-id="1374446923" data-res-action="addto" data-res-from="31" data-res-data="19723756"></a>
<a href="#" class="s-bg s-bg-12" title="收藏" hidefocus="true" data-res-level="0" data-res-fee="8" data-res-type="18" data-res-id="1374446923" data-res-action="subscribe"></a>
</div>
</li>
<li onmouseover="this.className='z-hvr'" onmouseout="this.className=''" class="">
<span class="no">4</span>
<a href="/song?id=1374304123" class="nm s-fc0 f-thide" title="你好">你好</a>
<div class="oper">
<a href="#" class="s-bg s-bg-11" title="播放" hidefocus="true" data-res-type="18" data-res-id="1374304123" data-res-action="play" data-res-from="31" data-res-data="19723756"></a>
<a href="#" class="u-icn u-icn-81" title="添加到播放列表" hidefocus="true" data-res-type="18" data-res-id="1374304123" data-res-action="addto" data-res-from="31" data-res-data="19723756"></a>
<a href="#" class="s-bg s-bg-12" title="收藏" hidefocus="true" data-res-level="0" data-res-fee="8" data-res-type="18" data-res-id="1374304123" data-res-action="subscribe"></a>
</div>
</li>
<li onmouseover="this.className='z-hvr'" onmouseout="this.className=''" class="">
<span class="no">5</span>
<a href="/song?id=1359356908" class="nm s-fc0 f-thide" title="晚安">晚安</a>
<div class="oper">
<a href="#" class="s-bg s-bg-11" title="播放" hidefocus="true" data-res-type="18" data-res-id="1359356908" data-res-action="play" data-res-from="31" data-res-data="19723756"></a>
<a href="#" class="u-icn u-icn-81" title="添加到播放列表" hidefocus="true" data-res-type="18" data-res-id="1359356908" data-res-action="addto" data-res-from="31" data-res-data="19723756"></a>
<a href="#" class="s-bg s-bg-12" title="收藏" hidefocus="true" data-res-level="0" data-res-fee="8" data-res-type="18" data-res-id="1359356908" data-res-action="subscribe"></a>
</div>
</li>
<li onmouseover="this.className='z-hvr'" onmouseout="this.className=''" class="">
<span class="no">6</span>
<a href="/song?id=1374701777" class="nm s-fc0 f-thide" title="平胸女子">平胸女子</a>
<div class="oper">
<a href="#" class="s-bg s-bg-11" title="播放" hidefocus="true" data-res-type="18" data-res-id="1374701777" data-res-action="play" data-res-from="31" data-res-data="19723756"></a>
<a href="#" class="u-icn u-icn-81" title="添加到播放列表" hidefocus="true" data-res-type="18" data-res-id="1374701777" data-res-action="addto" data-res-from="31" data-res-data="19723756"></a>
<a href="#" class="s-bg s-bg-12" title="收藏" hidefocus="true" data-res-level="0" data-res-fee="8" data-res-type="18" data-res-id="1374701777" data-res-action="subscribe"></a>
</div>
</li>
<li onmouseover="this.className='z-hvr'" onmouseout="this.className=''" class="">
<span class="no">7</span>
<a href="/song?id=1372300064" class="nm s-fc0 f-thide" title="憾">憾</a>
<div class="oper">
<a href="#" class="s-bg s-bg-11" title="播放" hidefocus="true" data-res-type="18" data-res-id="1372300064" data-res-action="play" data-res-from="31" data-res-data="19723756"></a>
<a href="#" class="u-icn u-icn-81" title="添加到播放列表" hidefocus="true" data-res-type="18" data-res-id="1372300064" data-res-action="addto" data-res-from="31" data-res-data="19723756"></a>
<a href="#" class="s-bg s-bg-12" title="收藏" hidefocus="true" data-res-level="0" data-res-fee="8" data-res-type="18" data-res-id="1372300064" data-res-action="subscribe"></a>
</div>
</li>
<li onmouseover="this.className='z-hvr'" onmouseout="this.className=''" class="">
<span class="no">8</span>
<a href="/song?id=1373632440" class="nm s-fc0 f-thide" title="Room to Fall">Room to Fall</a>
<div class="oper">
<a href="#" class="s-bg s-bg-11" title="播放" hidefocus="true" data-res-type="18" data-res-id="1373632440" data-res-action="play" data-res-from="31" data-res-data="19723756"></a>
<a href="#" class="u-icn u-icn-81" title="添加到播放列表" hidefocus="true" data-res-type="18" data-res-id="1373632440" data-res-action="addto" data-res-from="31" data-res-data="19723756"></a>
<a href="#" class="s-bg s-bg-12" title="收藏" hidefocus="true" data-res-level="0" data-res-fee="8" data-res-type="18" data-res-id="1373632440" data-res-action="subscribe"></a>
</div>
</li>
<li onmouseover="this.className='z-hvr'" onmouseout="this.className=''" class="">
<span class="no">9</span>
<a href="/song?id=1374313052" class="nm s-fc0 f-thide" title="キスだけで">キスだけで</a>
<div class="oper">
<a href="#" class="s-bg s-bg-11" title="播放" hidefocus="true" data-res-type="18" data-res-id="1374313052" data-res-action="play" data-res-from="31" data-res-data="19723756"></a>
<a href="#" class="u-icn u-icn-81" title="添加到播放列表" hidefocus="true" data-res-type="18" data-res-id="1374313052" data-res-action="addto" data-res-from="31" data-res-data="19723756"></a>
<a href="#" class="s-bg s-bg-12" title="收藏" hidefocus="true" data-res-level="0" data-res-fee="8" data-res-type="18" data-res-id="1374313052" data-res-action="subscribe"></a>
</div>
</li>
<li onmouseover="this.className='z-hvr'" onmouseout="this.className=''" class="">
<span class="no">10</span>
<a href="/song?id=1361615183" class="nm s-fc0 f-thide" title="你在哪里">你在哪里</a>
<div class="oper">
<a href="#" class="s-bg s-bg-11" title="播放" hidefocus="true" data-res-type="18" data-res-id="1361615183" data-res-action="play" data-res-from="31" data-res-data="19723756"></a>
<a href="#" class="u-icn u-icn-81" title="添加到播放列表" hidefocus="true" data-res-type="18" data-res-id="1361615183" data-res-action="addto" data-res-from="31" data-res-data="19723756"></a>
<a href="#" class="s-bg s-bg-12" title="收藏" hidefocus="true" data-res-level="0" data-res-fee="8" data-res-type="18" data-res-id="1361615183" data-res-action="subscribe"></a>
</div>
</li>
</ol>
"""
reg = "<li.*?<a href.*?>(.*?)</a>"

res = re.findall(reg,html,re.S) #因为其中有换行符,所以用re.S,使"."可以对其进行匹配。注意,返回的是组的列表

if res:
    for i in res:
        print(i)
else:
    print("没有匹配到...")

输出内容如下:

Beautiful People (feat. Khalid)
Heartbeat (BTS WORLD OST)
I Fell In Love With The Devil (Radio Edit)
你好
晚安
平胸女子
憾
Room to Fall
キスだけで
你在哪里

sub

格式:
re.sub(正则表达式, 要替换为的值或函数引用, 要进行匹配的内容)

用法一:中间参数为要替换为的内容
如果中间参数为要替换为的值,则将匹配到的内容( 可以匹配多个)替换,返回替换后的内容

用法二:中间参数为函数的引用(python独有)

import re

def add(temp):
    strNum = temp.group()   #strNum为997,因为group()是取匹配到的内容
    num = int(strNum) + 1
    return str(num)

ret = re.sub(r"\d+", add, "Python = 997")
print(ret)

'''运行结果如下:
Python = 998
'''

当用正则表达式匹配到后,就自动调用参数函数,并将正则表达式匹配到的对象传递给函数,并将函数的返回值作为要替换为的值

split

用法示例:

import re

ret = re.split(r":| ", "info:xiaozhang 33 shandong")    # 按照冒号和空格切割,返回的形式为列表
print(ret)
'''运行结果如下:
['info', 'xiaozhang', '33', 'shandong']
'''
上一篇下一篇

猜你喜欢

热点阅读