从零开始的Linux运维屌丝之路,资源免费分享平台   运维人员首选:简单、易用、高效、安全、稳定、社区活跃的开源软件

40、 re正则模块

发布:蔺要红05-29分类: Python

 

正则表达式

正则表达式本身是一种小型的、高度专业化的编程语言,而在python中,通过内嵌集成re模块,程序员们可以直接调用来实现正则匹配。正则表达式模式被编译成一系列的字节码,然后由用C编写的匹配引擎执行







一定注意:match和search和findall的区别
 
>>> re.findall("[0-9]",'abc123dEa3Eq1') #全局匹配,直到匹配结束返回全部的值/生成一个别表
['1', '2', '3', '3', '1']
#.group()把值取出

>>> re.match('[0-9]','abc123dEa3Eq1')   #没有匹配到值,从头匹配
>>> re.match('[0-9]','123dEa3Eq1').group() #没有匹配到值,从头匹配
'1'
#{2}代表匹配多少个
>>> re.match('[0-9]{2}','123dEa3Eq1')
<_sre.SRE_Match object; span=(0, 2), match='12'>
>>> re.match('[0-9]{4}','123dEa3Eq1')

import re
s = 'abc123dEa3Eq1'
match_res = re.search("[0-9]",s)
if match_res:  #判断是否争取,再取出值
    print(re.search("[0-9]",s).group())

#D:\python\python.exe F:/运维笔记/python/模块/re模块02.py
1
 . 和 ^
>>> re.search('..','abc123dEa3Eq1')
<_sre.SRE_Match object; span=(0, 2), match='ab'>
>>> re.search('^a','abc123dEa3Eq1')
<_sre.SRE_Match object; span=(0, 1), match='a'>
 *   
>>> re.search("2*","22222222yaohong")
<_sre.SRE_Match object; span=(0, 8), match='22222222'>
>>> re.search("ab*","abbcbb")
<_sre.SRE_Match object; span=(0, 3), match='abb'>
>>> re.search("ab*","abbbbbbbcbb")
<_sre.SRE_Match object; span=(0, 8), match='abbbbbbb'>

  +  
 
>>> re.search("ab+","abbbbbbbcbb")
<_sre.SRE_Match object; span=(0, 8), match='abbbbbbb'>
>>> re.search("ab+","abbcbb")
<_sre.SRE_Match object; span=(0, 3), match='abb'>
>>> re.search("ab+","ab")
<_sre.SRE_Match object; span=(0, 2), match='ab'>
>>> re.search(".+","abbaasdfafasdf554654")                 # .+全部
<_sre.SRE_Match object; span=(0, 20), match='abbaasdfafasdf554654'>


{n,m}
 

>>> re.search("[a-z]{1,10}",'a2lex')
<_sre.SRE_Match object; span=(0, 1), match='a'>
>>> re.search("[a-z]{1,10}",'2lex')
<_sre.SRE_Match object; span=(1, 4), match='lex'>

   |   
 
>>> re.search("[l|L]in",'lin')
<_sre.SRE_Match object; span=(0, 3), match='lin'>
>>> re.search("[l|L]in",'Lin')
<_sre.SRE_Match object; span=(0, 3), match='Lin'>
() 分组匹配       和groups 和搭配使用
 
>>> re.search("([a-z]+)([0-9]+)",'lin521').group()
'lin521'
>>> re.search("([a-z]+)([0-9]+)",'lin521').groups() # groups(1) 取第一个值
('lin', '521')
>>> re.search("(\w+)",'lin521').groups()
('lin521',)

\s 匹配空白字符
 
>>> re.findall('\s',"asd f3#1 23f % %@34&&")
[' ', ' ', ' ', ' ']
>>> re.findall('\s',"asd f3#1 23f % %@34\n \r &&")
[' ', ' ', ' ', ' ', '\n', ' ', '\r', ' ']
#re.sub使用
>>> re.sub('\s','',"asd f3#1 23f % %@34&&")
'asdf3#123f%%@34&&'

分组匹配
 
>>> a = '371326199004206715'
>>> re.search( '(?P<names>\d{3})(?P<city>\d{3})(?P<year>\d{4})',a).groups()
('371', '326', '1990')
>>> re.search( '(?P<names>\d{3})(?P<city>\d{3})(?P<year>\d{4})',a).groupdict() #用法,生成一个字典
{'names': '371', 'city': '326', 'year': '1990'}

split:以匹配到的作为分隔符
 
>>> re.split('\d+','lin2312yao1231hong12312')
['lin', 'yao', 'hong', '']
>>> re.findall('\d+','lin2312yao1231hong12312')
['2312', '1231', '12312']
>>> s = '5+3-7/3*99/4*2998+10*568/14'
>>> re.split('[-\*/+]',s)
['5', '3', '7', '3', '99', '4', '2998', '10', '568', '14']
>>> re.split('[+\-\*/]',s)
['5', '3', '7', '3', '99', '4', '2998', '10', '568', '14']
>>> re.split('[-\*/+]',s,maxsplit=2)
['5', '3', '7/3*99/4*2998+10*568/14']


sub匹配到的东西替换
 
>>> re.sub('\d+','=','lin2312yao1231hong12312|ma#ck-50lin') #全部替换
'lin=yao=hong=|ma#ck-=lin'
>>> re.sub('\d+','=','lin2312yao1231hong12312|ma#ck-50lin',count=2) #只替换前两个
'lin=yao=hong12312|ma#ck-50lin'
 
匹配邮箱
#整个字符串匹配成功则返回,否则返回None
>>> re.fullmatch('\w+@\w+\.(com|cn|edu)',"122123498@qqedu.com")
<_sre.SRE_Match object; span=(0, 19), match='122123498@qqedu.com'>
#此案例:.必须转义\.  后面(com|cn|edu)为一体必须用()
匹配手机号码
>>> re.fullmatch('1[3,5,8]\d{9}',"13653902018")
<_sre.SRE_Match object; span=(0, 11), match='13653902018'>
匹配url
>>> re.fullmatch('http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\(\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+',"http://linyaohong.com")
<_sre.SRE_Match object; span=(0, 21), match='http://linyaohong.com'>
匹配最里层的()
#找最里层的()

>>> re.search("\([^()]+\)",'1+21(3*25-5+(5+3)+26)').group()
'(5+3)'
 
先把规则定义好、再调用规则(代码优化,省掉解释器编译\w+@\w+\.(com|cn)的时间),这对于数量多的数据,能节省很多时间


>>> panttern = re.compile("\w+@\w+\.(com|cn)")
>>> panttern.fullmatch("122123498@qq.com")
<_sre.SRE_Match object; span=(0, 16), match='122123498@qq.com'>

 

标志含义

re.S(DOTALL)
使.匹配包括换行在内的所有字符
re.I(IGNORECASE)
使匹配对大小写不敏感
re.L(LOCALE)
做本地化识别(locale-aware)匹配,法语等
re.M(MULTILINE)
多行匹配,影响^和$
re.X(VERBOSE)
该标志通过给予更灵活的格式以便将正则表达式写得更易于理解
re.U
根据Unicode字符集解析字符,这个标志影响\w,\W,\b,\B

re.I #不区分大小写:

<_sre.SRE_Match object; span=(0, 6), match='lin521'>
>>> re.search("([a-z]+)([0-9]+)",'Lin521',re.I)
<_sre.SRE_Match object; span=(0, 6), match='Lin521'>

re.M #先去匹配了第一行  . 为任意一个字符结尾

>>> re.search("foo.$",'foo1\nfoo2\n',re.M)  #先去匹配了第一行 . 为任意一个字符结尾,虽然此处匹配的是结尾,但是会先去找第一行
<_sre.SRE_Match object; span=(0, 4), match='foo1'>
>>> re.search("foo.$",'foo1\nfoo2\n')
<_sre.SRE_Match object; span=(5, 9), match='foo2'>

re.S 加上之后  . 匹配任意字符,包含换行符

>>> re.search(".","\n")
>>> re.search(".","\n",re.S)
<_sre.SRE_Match object; span=(0, 1), match='\n'>

re.X #可以加注释

>>> re.search(". #test","Linyaohong") #匹配不到一个字符
>>> re.search(". #test","Linyaohong",re.X) #加上以后#test变成注释,
<_sre.SRE_Match object; span=(0, 1), match='L'>

一个案例找出所有的手机号码:

文本文档:
1,Alex Li,22,13651054684,Linux,2013-02-04
2,Jack Wang,28,13312331232,HR,2014-06-03
3,Mike Cao,29,15504231232,Sales,2013-05-06
4,Jack Chen,34,12404231232,HR,2011-02-01
5,Lu Haojie,21,15204231232,python,2013-08-12
6,14554678954
代码
# -*- coding:utf-8 -*-
import re
f = open('123','r',encoding='GBK')
data = f.read()
print(re.findall('[0-9]{11}',data))
print(re.findall('1[3|5-9]{1}[0-9]{9}',data))
#
D:\python\python.exe F:/运维笔记/python/模块/re模块.py
['13651054684', '13312331232', '15504231232', '12404231232', '15204231232', '14554678954']
['13651054684', '13312331232', '15504231232', '15204231232']



 
温馨提示如有转载或引用以上内容之必要,敬请将本文链接作为出处标注,如有侵权我会在24小时之内删除!

欢迎使用手机扫描访问本站