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('\w\w','Aa12  _+-'))  #得到两个连续的列表\数字\下划线
输出结果:
['Aa', '12']
print(re.findall('\w9\w','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\ncd')) #\n表⽰换⾏符
输出结果为:
['a1c', 'aac', 'a c']
print(re.findall('a.c','a a1c aaac a c jkda\ncd',re.DOTALL)) #re.DOTALL表⽰.可以代表所有的字符,包括换⾏符(\n当成⼀个字符来处理)
输出结果为:
['a1c', 'aac', 'a c', 'a\nc']
[]代表匹配⼀个字符,这⼀个字符可以⾃定义范围。# [a,]表⽰a或者,
print(re.findall('a[0-9]c','a a1d a2ca aaa a\nc',re.DOTALL))  #获得⼀个⾸尾两端为ac且中间为0~9中的⼀个数字的字符串列表。[0-9]中的横杠表⽰从哪到哪的意思,表⽰的是⼀个范围。
输出结果为:
['a2c']
print(re.findall('a[a-zA-Z]c','a aac a2ca aAc a\nc',re.DOTALL)) #获得⼀个⾸尾为ac的,中间是从a到z或从A到Z的字符串列表
输出结果为:
['aac', 'aAc']
print(re.findall('a[ac]c','a aac a2ca aAc a\nc',re.DOTALL)) #获得⼀个⾸尾为ac,中间为a或者c的字符串列表
输出结果为:
['aac']
如下例⼦会报错!因为当横杠在中间时表⽰的是范围!
print(re.findall('a[+-#/]c','a+c a-c a/c a*c a3c a\nc',re.DOTALL))
解决⽅法是改为[-+#/][+#/-][+\-#/] 将横杠改为中括号内的⾸尾,或者加上转义符反斜杠
print(re.findall('a[+\-#/]c','a+c a-c a/c a*c a3c a\nc',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\nc',re.DOTALL))  #表⽰获得⼀个长度为3,⾸尾是ac,中间不是数字的字符串列表
输出结果为:
['aac', 'a\nc']
.* 匹配任意0到⽆穷个字符,贪婪匹配,不常⽤。
print(re.findall('a.*c','a345ca34tcsf'))
输出结果:
['a345ca34tc']  #取到最远的c
.*?匹配任意0个到⽆穷个字符,⾮贪婪匹配,常⽤。
正则化一个5 5随机矩阵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="www.douniwan/1.mp4">逗你玩呢</a><a href="/2.mp4">葫芦娃</a>'))
输出结果为:
['www.douniwan/1.mp4', '/2.mp4']
'href="(.*?)"' 查:href="(.*?)"类似的内容,匹配成功后只输出括号内的内容。
\转义相关:
python本⾝没有正则表达式,是识别语法后交给cpython解释器去执⾏正则表达式。
print(re.findall('a\\\\c','a\c aac'))  #\是转义符,第⼀个转义第⼆个,第三个转移第四个,交给解释器为'a\\c',解释器语法识别转义,第⼀个转义第⼆个,就是'a\c'了
print(re.findall(r'a\\c','a\c aac'))  #r原⽣输⼊,解释器拿到的就是a\\c了
输出结果为:
['a\\c']  #没办法,只能这么显⽰,第⼀个转义第⼆个\,实际应理解为'a\c'
['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="www.douniwan/1.mp4">逗你玩呢</a><a href="/2.mp4">葫芦娃</a>'))
输出结果为:
<_sre.SRE_Match object; span=(14, 51), match='href="www.douniwan/1.mp4"'>  #match内容是完整内容,⽽不是组内内容!
如果没到,输出结果为:
None
res=re.findall('(href)="(.*?)"','<p>动感视频</p><a href="www.douniwan/1.mp4">逗你玩呢</a><a href="/2.mp4">葫芦娃</a>')
print(res)
输出结果:  #组内内容全部输出,⽆法指定。
[('href', 'www.douniwan/1.mp4'), ('href', '/2.mp4')]
up()功能可以指定输出组内的内容。
res=re.search('(href)="(.*?)"','<p>动感视频</p><a href="www.douniwan/1.mp4">逗你玩呢</a><a href="/2.mp4">葫芦娃</a>')  #注意匹配项⾥的两个元组print(res)
up(0))  #不传参或者参数为0表⽰匹配内容完整输出
up(1))  #输出匹配内容的第⼀处元组内容
up(2))  #输出匹配内容的第⼆处元组内容,如果传的参数⼤于实际元组数,则会报错
输出结果为:
href="www.douniwan/1.mp4"
href
www.douniwan/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(^)
repile⽅法
pattern=repile('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())

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。