re正则表达式

2019-04-23  本文已影响0人  清风徐来_简

今天来整理一下正则。有一天被同事问到正则的空格怎么匹配,然而因为长时间没有使用,一个简单的空格都不知道怎么匹配了,于是乎我就 \a \b \c 的一个一个回想,还没想到 \s,同事说:算了吧,我还是问度娘吧。

一、什么是正则

总之,正则表达式就是:定制规则,筛选出自己想要的字符串。还有:正则,和编程语言无关。

既然要定制规则,那么正则都有哪些匹配规则呢?别着急,往下走👇。

二、正则表达式匹配规则

说到这个正则的量词,就不得不说两个名词,贪婪匹配非贪婪匹配(惰性匹配)

三、python中如何使用正则

说完正则表达式,来看看python是怎么使用正则的。python中有个re模块,re中有一些方法,简单说一下。

import re
s = '1994-04-04334239238841038-12-3040561009-03-049'

# 一、re.findall(正则表达式,待匹配的字符串,flags=0)
ret = re.findall('1[\d]{3}-[01][\d]-[0123][\d]', s)
print(ret)  # 以列表的形式返回所有符合条件的筛选结果。
# 结果:['1994-04-04', '1038-12-30', '1009-03-04']

# 二、findall默认只显示分组中的,分组有优先级。
ret = re.findall('www\.(baidu|oldboy)\.com', 'www.baidu.com')
print(ret)
# 结果:['baidu']

# 三、加上  ?: 取消分组的优先
ret = re.findall('www\.(?:baidu|oldboy)\.com', 'www.baidu.com')
print(ret)
# 结果:['www.baidu.com']
import re
h5 = '<body><table><ul><li><a><name></a></li><li><img src="http://baidu.com/sss/aaa.jpg"/></li></table></boday>'

ret = re.findall('src="(.*?)"', h5)
print(ret[0])  
# 结果:http://baidu.com/sss/aaa.jpg

ret3 = re.search('src="(.*?)"', h5)
if ret3:
    print(ret3.group(1))  
# 结果:http://baidu.com/sss/aaa.jpg
re.S 的使用:
如果不使用re.S参数,则只在每一行内进行匹配,如果一行没有,就换下一行重新开始。
而使用re.S参数以后,正则表达式会将这个字符串作为一个整体,在整体中进行匹配。

import re
big_string_mutil = '''
我是kingname,我的微博号是:123
4567,'''
weibo = re.findall('微博号是:(.*?),', big_string_mutil)
print(weibo)  # []
weibo = re.findall('微博号是:(.*?),', big_string_mutil, re.S)
print(weibo)  # ['123\n4567']
import re
s ='hdn233jfhf456bj43rjf789ndhd'
ret = re.finditer('\d{2}',s)

print(ret)
# 返回一个存放匹配结果的迭代器:<callable_iterator object at 0x0000022A7FC7D8D0>

print(next(ret).group()) # 查看第一个结果:23
print(next(ret).group()) # 查看第二个结果:45

# print([i.group()for i in ret]) # 查看剩余结果
# 迭代器,节省空间
# for i in ret:
#     print(i.group())

a =ret.__next__()
print(a)
# 结果:<_sre.SRE_Match object; span=(15, 17), match='43'>

print(a.group())
# 结果:43
import re
s = '1994-04-04334239238841038-12-3040561009-03-049'
ret4 = re.match('1[\d]{3}-[01][\d]-[0123][\d]',s)

print(ret4) # 不会直接返回筛选结果:<_sre.SRE_Match object; span=(0, 10), match='1994-04-04'>

# print(ret.group())
if ret4:
    print(ret4.group())  # 只从头匹配,如果开头没找到就报错。
# 结果:1994-04-04

ret5 = re.match('a',s)
# print(ret5.group()) # AttributeError: 'NoneType' object has no attribute 'group'

print(ret5)
# 结果:None
# 找不到返回None,group时报错。
import re
s = '1994-04-04334239238841038-12-3040561009-03-049'
ret2 = re.search('1[\d]{3}-[01][\d]-[0123][\d]', s)

print(ret2)  # 不会直接返回筛选结果:<_sre.SRE_Match object; span=(0, 10), match='1994-04-04'>

print(ret2.group())  # group一下才能出来,但是只出来1个:1994-04-04

ret = re.search('q',s)
print(ret)   # 找不到返回None,group时报错,None类型当然没有group方法了。
# 结果:None
# print(ret.group())  # AttributeError: 'NoneType' object has no attribute 'group'

ret3 = re.search('A', s)
if ret3:
    print(ret3.group())  # 不存在时group()就会报错,所以要加上if
import re
big_sstring_mutil = '''我是kingname,我的微博号是:1234567,我是aaa,我的微博号是:bbb,我是ccc,我的微博号是:ddd,'''
r = re.search('我是(.*?),我的微博号是:(.*?),',big_sstring_mutil)
print(r.group())  # 我是kingname,我的微博号是:1234567, --> 全部结果
print(r.group(1))  # kingname   --> 取第一个括号中的内容
print(r.group(2))  # 1234567  --> 取第二个括号中的内容
import re
s ='hdnjfhfbjrjfndhd'

# 一、分割
ret = re.split('d.',s)
print(ret)  # 以正则表达式d.为分割,分割成列表
# 结果:['h', 'jfhfbjrjfn', 'd']

# 二、组合分割
ret1 = re.split('[dj]',s)
print(ret1) # 如果正则表达式在字符组里,先以d分割再以j分割。
# 结果:['h', 'n', 'fhfb', 'r', 'fn', 'h', '']

# 三、分组在 split 中也有特权
rett = re.split('(d.)',s) # 会保留分组内的内容
print(rett) # ['h', 'dn', 'jfhfbjrjfn', 'dh', 'd']

# 四、取消特权
ret2 = re.split('(?:d.)',s) # 这样就不会保留分组内的内容了,取消优先
print(ret2) # ['h', 'jfhfbjrjfn', 'd']
import re
s = 'hdnjfhfbjrjfndhd'

# re.sub()
ret2 = re.sub('d..', 'H', s, 1)  # 【表达式表示替换内容,要替换的新元素,替换对象,替换次数】
print(ret2)
# 结果:hHfhfbjrjfndhd

ret4 = re.sub('d..', str(2), s, 1)  # 【替换成的内容必须是字符串】
print(ret4)
# 结果:h2fhfbjrjfndhd

# re.subn()
ret3 = re.subn('d..', 'H', s)  # 【返回元组,前面是替换完的结果,后面是替换的次数】
print(ret3)
# 结果:('hHfhfbjrjfnH', 2)
import re
s = '''wo men 123 shi zu guo de 32144 hua guo,
wo men 34523 shi zu guo de 3256144 hua guo,
wo men 4234 shi zu guo de 44345 hua guo,
wo men 12345433 shi zu guo de 4323125 hua guo,'''

ret = re.sub('\d+', "afanti", s)
print(ret)
结果:
wo men afanti shi zu guo de afanti hua guo,
wo men afanti shi zu guo de afanti hua guo,
wo men afanti shi zu guo de afanti hua guo,
wo men afanti shi zu guo de afanti hua guo,
# 将正则表达式编译成一个正则表表达式对象。
# 如果一个正则表达式在程序中只用一次,就没必要编译了。
# 如果同一个正则表达式要被多次使用时,就需要对表达式进行编译,以便后续使用。
import re
s ='hdn233jfhf456bj43rjf789ndhd'
obj = re.compile('\d{2}')

ret = obj.findall(s)
print(ret)
# 结果 :['23', '45', '43', '78']
# 编译,节省时间

四、再来举几个栗子

import re
exp = "1-2*(60+(-40.35/5)-(-4*3))"

ret = re.findall('\d',exp)
print(ret)  # 只有单个数
# 结果:['1', '2', '6', '0', '4', '0', '3', '5', '5', '4', '3']

ret1 = re.findall('\d+',exp)
print(ret1) # 只有整数(有多位)
# 结果:['1', '2', '60', '40', '35', '5', '4', '3']

ret2 = re.findall('\d+\.\d+',exp)
print(ret2) # 只有小数
# 结果:['40.35']

r = re.findall('\d+|\d+\.\d+',exp)
print(r) # 短的放前面只会出现短的,长的不会出现
# 结果:['1', '2', '60', '40', '35', '5', '4', '3']

ret3 = re.findall('\d+\.\d+|\d+',exp)
print(ret3) # 所以如果有长的要把长的放前面
# 结果:['1', '2', '60', '40.35', '5', '4', '3']

ret4 = re.findall('\d+\.\d+|(\d+)',exp)
print(ret4) # findall 优先级,只留下括号里的
# 结果:['1', '2', '60', '', '5', '4', '3']
ret4.remove('')
print(ret4)
# 结果:['1', '2', '60', '5', '4', '3']

r = re.findall('-?\d+\.\d+|-?\d+',exp)
print(r)
# 所有的数字,包括小数和整数。
# 结果:['1', '-2', '60', '-40.35', '5', '-4', '3']
import re
ret = re.search("<(\w+)>(\w+)</(\w+)>","<h1>hello</h2>")

print(ret.group())  # group  组  :<h1>hello</h2>
print(ret.group(0))  # 0 默认全部,同上  :<h1>hello</h2>
print(ret.group(1))  # 第 1 组  :h1
print(ret.group(2))  # 第 2 组  :hello

# 现在有个要求,字符串左右必须一致都是h1或都是h2(这就是标签),怎么做?
# 1,用组的位置的方式
ret = re.search(r"<(\w+)>(\w+)</\1>","<h1>hello</h1>")
print(ret.group())
# 结果:<h1>hello</h1>

# 2,用组的名字的方式
# 可以给分组起名字(?P<名字>表达式)【名字在组内】
ret = re.search("<(?P<tag>\w+)>(\w+)</(?P=tag)>","<h1>hello</h1>")
print(ret)  # <_sre.SRE_Match object; span=(0, 14), match='<h1>hello</h1>'>
print(ret.group())  # <h1>hello</h1>
print(ret.group('tag'))  # h1
s = "ghjk我爱中国gh中华人民共和国万岁jk关关雎鸠fghjke在河之洲eergfds窈窕淑女dtyuimnbv君子好逑"
import re
ret = re.findall('[\u4e00-\u9fa5]+',s)
print(ret)
# ['我爱中国', '中华人民共和国万岁', '关关雎鸠', '在河之洲', '窈窕淑女', '君子好逑']

五、心态很重要!!!!!!

人生苦短,我用python

上一篇 下一篇

猜你喜欢

热点阅读