python学习24天----re模块py正则random模块

Posted piaolaipiaoqu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python学习24天----re模块py正则random模块相关的知识,希望对你有一定的参考价值。

1.转义符()

       转义符赋予了一个字符一个特殊的意义,如n变为了 就表示换行符

1)python中的转义

#在字符串前加r表示取消字符串中的所有转移

技术图片
print("C:a.txt")
print(r"C:a.txt")
输出:
C:.txt
C:a.txt
View Code

#在转义符前再加一个就表示取消转义,恢复其原本的意义

技术图片
print("C:a.txt")
print("C:\a.txt")
输出:
C:.txt
C:a.txt
View Code

#在正则表达式中,遇到正则转义,直接在之前加r

总结:在python中‘\\n‘才能匹配到‘\n‘ ,所以只要早测试工具测试成功,那在程序中采用加r的方式即可,即r‘\n‘匹配r‘ ‘

2)正则中的转义

①‘(’    在正则中匹配一个(

②[()+*?/$.]   在字符组中一些特殊的字符会显出原形(即表示原本的意义),如()+*?/等符号

③所有的w d s 在字符组中都表示它原本的意义

④[-]       减号-只有写在字符组的首位的时候表示普通的减号,写在其他位置表示范围,如[1-9]就表示1-9,如果就是想匹配减号,可以写为[1-9]

2.re模块

       使用先导入:import re

1)字符串的匹配

①findall(必会)

#语法:re.findall(‘正则表达式‘,‘待匹配的字符串‘)

#参数:正则表达式,待匹配字符串  返回值类型:列表 返回值个数:1 返回值内容:所有匹配上的项;若没有匹配上,就是一个没有值的列表

技术图片
import re
ret = re.findall(d,"47823dao123")
print(ret)
输出:
[4, 7, 8, 2, 3, 1, 2, 3]
View Code

②search(必会)

#语法:re.search(‘正则表达式‘,‘待匹配的字符串‘)

#参数:正则表达式,待匹配字符串 ;返回值类型:正则匹配结果的对象 ;返回值个数:1; 返回值内容列表: 如果匹配上了就返回对象,如果没有匹配上就返回None

技术图片
import re
ret2 = re.search(d,"47823dao123")
ret3 = re.search(d,"jaosfjo")
print(ret2)
print(ret3)
输出:
<_sre.SRE_Match object; span=(0, 1), match=4>
None
View Code

#返回的对象通过group来匹配到的第一个结果,其他结果无法获取

技术图片
import re
ret2 = re.search(d,"47823dao123")
ret3 = re.search(d+,"47823dao123")
print(ret2.group())
print(ret3.group())
输出:
4
47823
View Code

③match

       表示从头开始匹配,不管正则表达式写成什么样,都默认在最前面加一个^,然后再做和search同样的工作

技术图片
import re
ret2 = re.match(d+,"47823dao123")
ret3 = re.match(d+,"$%47823dao123")
print(ret2)
print(ret3)       #输入None
print(ret2.group())
print(ret3.group())  #报错::AttributeError: ‘NoneType‘ object has no attribute ‘group‘
输出:
<_sre.SRE_Match object; span=(0, 5), match=47823>
None
47823
报错:
AttributeError: NoneType object has no attribute group
View Code

#要想search实现和match一样的效果,可以再search的正则表达式最前放加一个^

技术图片
import re
ret2 = re.search(^d+,"47823dao123")
ret3 = re.search(^d+,"^$%47823dao123")
print(ret2)
print(ret3)       #输入None
print(ret2.group())
print(ret3.group())
输出:
<_sre.SRE_Match object; span=(0, 5), match=47823>
None
47823
报错:AttributeError: NoneType object has no attribute group
View Code

#一般在用search匹配时,可以先用if语句判断一下是否匹配到结果,如果匹配到了,再用group输入匹配到的结果(可避开报错)

技术图片
import re
ret2 = re.search(^d+,"47823dao123")
ret3 = re.search(^d+,"^$%47823dao123")
if ret2:print(ret2.group())
if ret3:print(ret3.group())
输出:
47823
View Code

2)字符串的替换

回顾:replace对字符串的替换

技术图片
print("HelloWorld".replace("o","e"))
输出:
HelleWerld
View Code

#replace知道替换次数

技术图片
print("HelloWorld".replace("o","e",1))
输出:
HelleWorld
View Code

①sub(***)

#语法:re.search(‘正则表达式‘,‘将匹配到的字符串替换成什么‘,‘待匹配字符产‘)

技术图片
import re
ret = re.sub(d,W,Hello8orld)
ret2 = re.sub(d+,x,123*123)
print(ret)
print(ret2)
输出:
HelloWorld
x*x
View Code

注:python不能直接操作硬盘中的数据,只能先将硬盘中的数据读到内存中,再操纵内存

#sub指定替换的次数

技术图片
import re
ret = re.sub(d+,x,123*123*123,1)
print(ret)
输出:
x*123*123
View Code

②sub2(***)

#语法:re.search(‘正则表达式‘,‘将匹配到的字符串替换成什么‘,‘待匹配字符产‘)

特点:和sub的区别在于他会将匹配到的次数计算出来,将替换后的字符串与匹配到的次数以元组的形式返回

技术图片
import re
ret = re.subn("d+","X","123dad*sas789jdai456")
ret2 = re.subn("d","X","123dad*sas789jdai456")
print(ret)
print(ret2)
输出:
(Xdad*sasXjdaiX, 3)
(XXXdad*sasXXXjdaiXXX, 9)
View Code

3)字符串的切割

回顾:字符串的split方法切割

技术图片
print("阿狸_泽拉斯_塞拉斯_拉克丝".split("_"))
输出:
[阿狸, 泽拉斯, 塞拉斯, 拉克丝]
View Code

①split(***)

#语法:re.split(‘正则表达式‘,‘字符串‘)   

#将字符串以正则匹配到的字符串为分割符进行分割,然后将分割后的字符串以元组的形式返回

技术图片
import re
ret = re.split("d+","阿狸123泽拉斯456塞拉斯789拉克丝")
print(ret)
输出:
[阿狸, 泽拉斯, 塞拉斯, 拉克丝]
View Code

4)进阶方法(爬虫/自动化开发必会)

①compile(*****)---------时间效率

#写的则正则表达式首先要变成python解释器能理解的代码,然后再通过这些代码查找你要匹配的内容,但是如果是一个特别长的正则表达式,并且经常使用同一个方法,那么每次使用时都会编译一遍,导致程序效率降低,所以可以利用compile方法将正则表达式先进行编译

技术图片
#匹配复数
import re
ret = re.compile(-0.d+|-[1-9]d+(.d+)?)
res1 = ret.search("sajod-20ada")
res2 = ret.search("-30jdiaojd")
res3 = ret.search("jdiaojd-40")
print(res1.group())
print(res2.group())
print(res3.group())
输出:
-20
-30
-40
View Code

注:如果正则表达式只用一次不会节省时间,只有在多次使用某一个相同的正则表达式的时候,这个compile才会提高程序的效率

②finditer(*****)-----空间效率

#如果一次匹配出来的是海量的时候,不要用findall直接获取匹配到的内容,应该用finditer,通过finditer返回的数据是一个可迭代对象(可一个一个取值),便利迭代器拿到的是一个对象,再通过group取到每一个的值

技术图片
import re
res = re.finditer("d","a21asd5ad5959da2789da")
for r in res:
    print(r.group())
输出:
2
17
View Code

注:所以的空间效率的提升,都代表着时间的提速

总结:在re模块中,findall方法和split方法都返回一个列表;并且findall和split遇到分组会出现问题,如下:

3.正则表达式和python的re模块

1)findall会优先显示分组中的内容,要想取消分组优先,可以在分组的第一个位置前加一个?: 即(?:正则表达式)

技术图片
import re
ret = re.findall(-0.d+|-[1-9]d*(.d+)?,-1asdada-200)
print(ret)   #正常情况下应该打印处-1和-200,但是输出了[‘‘, ‘‘]
res = re.findall("www.baidu.com|www.qq.com","www.qq.com")
print(res) #输出[‘www.qq.com‘]
rep = re.findall("www.(baidu|qq).com","www.qq.com")    #正则表达式表达的意思同上,但是匹配到的内容不是想要的内容
print(rep)      #输出:[‘qq‘],,即只匹配到了分组中的内容
输出:
[‘‘, ‘‘]
[www.qq.com]
[qq]
View Code

#在分组内的第一个位置写【?:】表示取消这个组的分组优先

技术图片
import re
ret = re.findall(-0.d+|-[1-9]d*(?:.d+)?,-1asdada-200)
print(ret)
rep = re.findall("www.(?:baidu|qq).com","www.qq.com")
print(rep)   
输出:
[-1, -200]
[www.qq.com]
View Code

2)split方法在遇到分组的时候,会保留分组内,被切掉的内容

技术图片
import re
ret = re.split("(d+)","阿狸123泽拉斯456塞拉斯789拉克丝")
print(ret)
输出:
[阿狸, 123, 泽拉斯, 456, 塞拉斯, 789, 拉克丝]
View Code

3)search和分组:如果search方法中有分组,通过group(n)就能够获取到group中匹配的内容

技术图片
import re
ret = re.search(d+(.d+)(.d+)(.d+)?,1.2.3.4-2*(60+(-40.35/5)-(-4*3)))
print(ret.group())
print(ret.group(1))
print(ret.group(2))
print(ret.group(3))
输出:
1.2.3.4
.2
.3
.4
View Code

注:在所有的re模块方法中,只有findall和split方法在遇到分组是会有问题,其他方法都正常

4.分组练习

1)从表达式1-2*(60+(-40.35/5)-(-4*3))获取到所有整数

①直接通过d匹配,不能实现

技术图片
import re
print(re.findall(d+,"1-2*(60+(-40.35/5)-(-4*3))"))
输出:
[1, 2, 60, 40, 35, 5, 4, 3]
View Code

②匹配出每一个数字(整数和小数都显示),不管正负

技术图片
import re
ret = re.findall(d+(?:.d+)?,"1-2*(60+(-40.35/5)-(-4*3))")
print(ret)
输出:
[1, 2, 60, 40.35, 5, 4, 3]
View Code

③利用分组优先显示的特点,先取到分组内部的值(即整数),然后再把匹配到的空字符去掉

技术图片
import re
ret = re.findall(d+(?:.d+)|(d+),"1-2*(60+(-40.35/5)-(-4*3))")
print(ret)
ret.remove(‘‘)
print(ret)
输出:
[1, 2, 60, ‘‘, 5, 4, 3]
[1, 2, 60, 5, 4, 3]
View Code

注:当不想要的字符串和想要的字符串发生了冲突,可以把不想要的字符串先匹配出来,然后让其不显示

2)标签匹配,对于如下标签

<a>wahaha</a>

①取出<a>

技术图片
import re
ret = re.findall(<w+>,r"<a>wahaha</a>")
print(ret)
输出:
[<a>]
View Code

②只取出a

技术图片
import re
ret = re.findall(<(w+)>,r"<a>wahaha</a>")   #加上分组,使其优先显示
print(ret)
输出:
[a]
View Code

③取出里面内容,如wahaha

技术图片
import re
ret = re.findall(>(w+)<,r"<a>wahaha</a>")   #加上分组,使其优先显示
print(ret)
输出:
[wahaha]
View Code

④通过search的方式取值

技术图片
import re
ret = re.search(<(w+)>(w+)</(w+)>,"<a>wahaha</a>")
print(ret.group())
print(ret.group(1))
print(ret.group(2))
输出:
<a>wahaha</a>
a
wahaha
View Code

3)分组命名(两个名字相同的分组必须一样)

       当需要用到一个部分匹配到的内容和另一个地方必须一样的时候,可以用到分组命名

<?P<name>正则表达式>表示给分组起名字

<?P=name>表示使用这个分组,这里匹配到的内容应和分组中的内容完全相同

技术图片
import re
ret = re.search(<(?P<name>w+)>w+</(?P=name)>,"<h1>hello</h1>")
print(ret.group("name"))
输出:
h1
View Code

#正常情况下也可使用分组命名的方式获取匹配到的值

技术图片
import re
ret = re.search(r<(?P<X>w+)>(?P<Z>w+)</(w+)>,r<a>hello</b>)
print(ret.group())
print(ret.group(X))
print(ret.group(Z))
输出:
<a>hello</b>
a
hello
View Code

4)通过索引使用分组:1表示使用第一组,即匹配到的内容必须和第一个分组中的内容完全相同

    #分组命名第二种写法:如果不给组起名字,也可以用序号来找到对应的组,表示要找的内容和前面的组内容一致,获取的匹配结果可以直接用group(序号)拿到对应的值

技术图片
import re
ret = re.search(r"<(w+)>w+</1>","<h1>hello</h1>")
print(ret.group(1))
输出:
h1
View Code

6.random模块

随机:在某个范围内取到的每一个值的概率都是相同的

#和随机有关的操作,都用到random模块(如抽奖、彩票、发红包、验证码、洗牌)

1)随机小数

#产生0-1之内的随机小数

技术图片
import random
print(random.random())
输出:
0.9196700983181918
View Code

#取到某个特定范围内的小数

技术图片
import random
print(random.uniform(2,5)) #取2-5之间的随机小数
输出:
2.8264542818054768
View Code

2)随机整数

#包含范围内的随机整数

技术图片
import random
print(random.randint(10,20))   #获取一个10-20之间的随机数,包含边界值
输出:
18
View Code

#左闭右开区间取随机数

技术图片
import random
print(random.randrange(10,20))    #有可能取到10,但取不到20
输出:
17
View Code

#在[1,10]不包含10在内的范围内随机取奇数(即间隔两个数取一个)

技术图片
import random
print(random.randrange(1,10,2))
输出:
5
View Code

3)随机抽取

#随机抽取一个值

技术图片
import random
lst = ["阿狸","泽拉斯","拉克丝",("惩戒之箭","韦鲁斯")]
print(random.choice(lst))
输出:
泽拉斯
View Code

#随机获取多个值

技术图片
import random
lst = ["阿狸","泽拉斯","拉克丝",("惩戒之箭","韦鲁斯")]
print(random.sample(lst,2))
输出:
[阿狸, (惩戒之箭, 韦鲁斯)]
View Code

4)打乱顺序(在原列表的基础上打乱顺序 )

技术图片
import random
lst = ["阿狸","泽拉斯","拉克丝",("惩戒之箭","韦鲁斯")]
random.shuffle(lst)
print(lst)
输出:
[阿狸, (惩戒之箭, 韦鲁斯), 拉克丝, 泽拉斯]
View Code

注:永远不要起和知道的模块名相同的文件名

 

以上是关于python学习24天----re模块py正则random模块的主要内容,如果未能解决你的问题,请参考以下文章

py12 正则表达式 re模块

python常用模块:collections模块和re模块(正则表达式详解)

py爬虫 —— py爬虫基础re库

python之路---24 正则表达式 re模块

python的re正则表达式模块学习

python之正则re模块