20181206(re,正则表达式,哈希)

 

1、re&正则表达式

2、hashlib

 

一:re模块&正则表达式

正则:正则就是用一些具有特殊含义的符号组合到一起(称为正则表达式)来描述字符或者字符串的方法。或者说:正则就是用来描述一类事物的规则。(在Python中)它内嵌在Python中,并通过 re 模块实现。正则表达式得到的是一个列表。

import re
w 匹配字母数字下划线:
res = re.findall('alex','hahhaha alex is alex is dsb')  #逐字匹配,一旦匹配成功就会完整跳过匹配上的字符串。例如在abcabcabca中,能够寻找到的abca为括号中的内容(abca)bc(abca)
print(res)
输出结果:
['alex', 'alex']
print(re.findall('w','Aa12 _+-'))
输出结果:
['A', 'a', '1', '2', '_']
print(re.findall('ww','Aa12 _+-'))   #得到两个连续的列表数字下划线
输出结果:
['Aa', '12']
print(re.findall('w9w','Aa912 s9_+-'))  #得到三个连续的列表数字下划线,其中中间的字符必须是9
输出结果:
['a91', 's9_']

 

print(re.findall('^alex','alex id alex'))   #^表示近从头开始匹配
print(re.findall('^alex',' alex id alex'))  #此处开头有空格
输出结果:
['alex']
[]


print(re.findall('alex$',' alex id alex'))  #$表示从文件末尾开始寻找,末尾没有就返回空列表
输出结果:
['alex']

. 代表一个字符,该字符可以是除换行符之外的任意字符
print(re.findall('a.c','a a1c aaac a c jkdsajfkd')) #得到三个字符,首尾是ac,中间是除换行符之外的任意字符
输出结果['a1c', 'aac', 'a c']

print(re.findall('a.c','a a1c aaac a c jkda cd')) # 表示换行符
输出结果为:
['a1c', 'aac', 'a c']
print(re.findall('a.c','a a1c aaac a c jkda cd',re.DOTALL)) #re.DOTALL表示.可以代表所有的字符,包括换行符( 当成一个字符来处理)
输出结果为:
['a1c', 'aac', 'a c', 'a c']

[]代表匹配一个字符,这一个字符可以自定义范围。# [a,]表示a或者,!!!
print(re.findall('a[0-9]c','a a1d a2ca aaa a c',re.DOTALL))  #获得一个首尾两端为ac且中间为0~9中的一个数字的字符串列表。[0-9]中的横杠表示从哪到哪的意思,表示的是一个范围。
输出结果为:
['a2c']
print(re.findall('a[a-zA-Z]c','a aac a2ca aAc a c',re.DOTALL)) #获得一个首尾为ac的,中间是从a到z或从A到Z的字符串列表
输出结果为:
['aac', 'aAc']
print(re.findall('a[ac]c','a aac a2ca aAc a c',re.DOTALL)) #获得一个首尾为ac,中间为a或者c的字符串列表
输出结果为:
['aac']

如下例子会报错!因为当横杠在中间时表示的是范围!
print(re.findall('a[+-#/]c','a+c a-c a/c a*c a3c a c',re.DOTALL))
解决方法是改为[-+#/][+#/-][+-#/] 将横杠改为中括号内的首尾,或者加上转义符反斜杠
print(re.findall('a[+-#/]c','a+c a-c a/c a*c a3c a c',re.DOTALL))
修改后的输出结果为:
['a+c', 'a-c', 'a/c']

       
重复匹配: *+{n,m}均不能单独使用,左侧必须有字符。  
       
?代表左边那一个字符出现0次到1次
print(re.findall('ab?','a ab abb abbb a123b a123bbb'))
输出结果:
['a', 'ab', 'ab', 'ab', 'a', 'a']

*代表左边那一个字符出现0次到无穷次
print(re.findall('ab*','a ab abb abbb a123b a123bbb'))
输出结果:
['a', 'ab', 'abb', 'abbb', 'a', 'a']

+代表左边的那一个字符出现1次到无穷次
print(re.findall('ab+','a ab abb abbb a123b a123bbb'))
输出结果:
['ab', 'abb', 'abbb']

{n,m}代表左边那一个字符出现n次到m次
print(re.findall('ab{1,3}','a ab abb abbb a123b a123bbb'))
print(re.findall('ab{1,}','a ab abb abbb a123b a123bbb')) #等同ab+
print(re.findall('ab{0,}','a ab abb abbb a123b a123bbb'))  #等同ab*
print(re.findall('ab{3}','a ab abb abbb a123b a123bbb'))  #指定出现3次
输出结果为:
['ab', 'abb', 'abbb']
['ab', 'abb', 'abbb']
['a', 'ab', 'abb', 'abbb', 'a', 'a']
['abbb']

[^]取反:
print(re.findall('a[^0-9]c','a a1d a2ca aac a c',re.DOTALL))  #表示获得一个长度为3,首尾是ac,中间不是数字的字符串列表
输出结果为:
['aac', 'a c']

.* 匹配任意0到无穷个字符,贪婪匹配,不常用。
print(re.findall('a.*c','a345ca34tcsf'))
输出结果:
['a345ca34tc']  #取到最远的c

.*?匹配任意0个到无穷个字符,非贪婪匹配,常用。
print(re.findall('a.*?c','a31c34atcsf'))  #表示碰到首尾是ac的就取出,就近原则。可能会输出过个结果。
输出结果为:
['a31c', 'atc']

|代表或者,连接两个正则表达式。
print(re.findall('company|companies','Too many companies have gone bankrupt, and the next one is my company')) #寻找company或companies
输出结果为:
['companies', 'company']        
       

()分组
print(re.findall('compan(y|ies)','Too many companies have gone bankrupt, and the next one is my company'))  #匹配成功后只输出括号内的字符
输出结果为:        
['ies', 'y']        
       
print(re.findall('compan(?:y|ies)','Too many companies have gone bankrupt, and the next one is my company')) #findall的结果不是匹配的全部内容,而是组内的内容。?:可以让结果为匹配的全部内容。
输出结果:
['companies', 'company']

小综合应用,寻找视频链接地址:

print(re.findall('href="(.*?)"','<p>动感视频</p><a href="https://www.douniwan.com/1.mp4">逗你玩呢</a><a href="https://www.xxx.com/2.mp4">葫芦娃</a>'))
输出结果为:
['https://www.douniwan.com/1.mp4', 'https://www.xxx.com/2.mp4']

'href="(.*?)"' 查找:href="(.*?)"类似的内容,匹配成功后只输出括号内的内容。

 

转义相关:

python本身没有正则表达式,是识别语法后交给cpython解释器去执行正则表达式。

print(re.findall('a\\c','ac aac'))  #是转义符,第一个转义第二个,第三个转移第四个,交给解释器为'a\c',解释器语法识别转义,第一个转义第二个,就是'ac'了
print(re.findall(r'a\c','ac aac'))  #r原生输入,解释器拿到的就是a\c了
输出结果为:
['a\c']  #没办法,只能这么显示,第一个转义第二个,实际应理解为'ac'
['a\c']

 

re.I 忽略大小写

print(re.findall('alex','my name is alex Alex is sb alex Alex',re.I))
输出结果:
['alex', 'Alex', 'alex', 'Alex']

 

re.M

msg="""
my name is egon
sfaf egon
sdf23 egon
"""
print(re.findall('egon$',msg,))  #只从后面找第一个,msg内容看作是一行的内容
输出结果为:
['egon']


msg="""
my name is egon
sfaf egon
sdf23 egon
"""
print(re.findall('egon$',msg,re.M))  #识别换行符,找到每一个line最后的字符
输出结果为:
['egon', 'egon', 'egon']

 

re模块的其他方法:

re.search方法:找到一次就不找了,如果找不到就返回None。

print(re.search('href="(.*?)"','<p>动感视频</p><a href="https://www.douniwan.com/1.mp4">逗你玩呢</a><a href="https://www.xxx.com/2.mp4">葫芦娃</a>'))
输出结果为:
<_sre.SRE_Match object; span=(14, 51), match='href="https://www.douniwan.com/1.mp4"'>  #match内容是完整内容,而不是组内内容!
如果没找到,输出结果为:
None

res=re.findall('(href)="(.*?)"','<p>动感视频</p><a href="https://www.douniwan.com/1.mp4">逗你玩呢</a><a href="https://www.xxx.com/2.mp4">葫芦娃</a>')
print(res)
输出结果:  #组内内容全部输出,无法指定。
[('href', 'https://www.douniwan.com/1.mp4'), ('href', 'https://www.xxx.com/2.mp4')]


re.serch.group()功能可以指定输出组内的内容。
res=re.search('(href)="(.*?)"','<p>动感视频</p><a href="https://www.douniwan.com/1.mp4">逗你玩呢</a><a href="https://www.xxx.com/2.mp4">葫芦娃</a>')   #注意匹配项里的两个元组
print(res)
print(res.group(0))  #不传参或者参数为0表示匹配内容完整输出
print(res.group(1))  #输出匹配内容的第一处元组内容
print(res.group(2))  #输出匹配内容的第二处元组内容,如果传的参数大于实际元组数 ,则会报错
输出结果为:
href="https://www.douniwan.com/1.mp4"
href
https://www.douniwan.com/1.mp4

 

re.match()等同于re.search(^)

print(re.findall('alex','alex is alex is alex'))
print(re.search('alex','is alex is alex'))
print(re.search('^alex','is alex is alex'))
print(re.match('alex','alex is alex is alex'))
输出结果为:
['alex', 'alex', 'alex']  #findall查找所有
<_sre.SRE_Match object; span=(3, 7), match='alex'>  #查找到一个就结束
None   #只从头开始找,如果首字符没有匹配就返回None
<_sre.SRE_Match object; span=(0, 4), match='alex'>  #只从头开始找,如果首字符没有匹配就返回None,等同于re.search(^)

 

re.compile方法
pattern=re.compile('alex')  #目标字符
print(pattern.findall('alex is alex is alex'))
print(pattern.search('alex is alex is alex'))
print(pattern.match('alex is alex is alex'))
输出结果为:
['alex', 'alex', 'alex']
<_sre.SRE_Match object; span=(0, 4), match='alex'>
<_sre.SRE_Match object; span=(0, 4), match='alex'>

 

练习

计算器作业

msg="1-2*(60+(-40.35/5)-(-4*3))"
print(re.findall('D?(-?d+.?d*)',msg))
输出结果:
['1', '2', '60', '-40.35', '5', '-4', '3']

 

二、hashlib模块

hashlib下面有许多算法,hash本身也是一种算法。

用途:对数据进行校验
hash:是一种算法,该算法接收一系列的数据,运算得到返回值
返回值是hash值
三大特性:
"""
1、只要传入的内容一样,那么得到的hash值就一定是一样的
2、只要采用hash算法固定,无论传入的内容多大,hash值的长度是固定的
3、hash值不可逆,即不可能通过hash值逆推出内容

1+2=》文件完整性校验
3==》加密传输的数据
"""

 

import hashlib

m=hashlib.md5()   #此处采用md5哈希算法
m.update('你好'.encode('utf-8'))  #按照utf8格式编码。
m.update('hello'.encode('utf-8'))
print(m.hexdigest())
输出结果为:
65c83c71cb3b2e2882f99358430679c3

也可以写成:
m=hashlib.md5()   #此处采用md5哈希算法
m.update('你好hello'.encode('utf-8'))  #按照utf8格式编码。
print(m.hexdigest())
输出结果为:
65c83c71cb3b2e2882f99358430679c3  #哈希值与上例中相同。



m1=hashlib.md5(b'hello') #也可以直接输入英文,前面用b表示是Bytes类型。
print(m1.hexdigest())

 

 

原文地址:https://www.cnblogs.com/realadmin/p/10078829.html