python之模块分类(六)
一、概念
re模块是python独有的匹配字符串的模块,该模块中提供的很多功能是基于正则表达式实现的,而正则表达式是对字符串进行模糊匹配,提取自己需要的字符串部分,他对所有的语言都通用。注意:
- re模块是python独有的
- 正则表达式所有编程语言都可以使用
- re模块、正则表达式是对字符串进行操作
二、常用正则表达式符号
'.' 默认匹配除\n之外的任意一个字符,若指定flag DOTALL,则匹配任意字符,包括换行 '^' 匹配字符开头,若指定flags MULTILINE,这种也可以匹配上(r"^a","\nabc\neee",flags=re.MULTILINE) '$' 匹配字符结尾,或e.search("foo$","bfoo\nsdfsf",flags=re.MULTILINE).group()也可以 '*' 匹配*号前的字符0次或多次,re.findall("ab*","cabb3abcbbac") 结果为['abb', 'ab', 'a'] '+' 匹配前一个字符1次或多次,re.findall("ab+","ab+cd+abb+bba") 结果['ab', 'abb'] '?' 匹配前一个字符1次或0次 '{m}' 匹配前一个字符m次 '{n,m}' 匹配前一个字符n到m次,re.findall("ab{1,3}","abb abc abbcbbb") 结果'abb', 'ab', 'abb'] '|' 匹配|左或|右的字符,re.search("abc|ABC","ABCBabcCD").group() 结果'ABC' '(...)' 分组匹配,re.search("(abc){2}a(123|456)c", "abcabca456c").group() 结果 abcabca456c '\A' 只从字符开头匹配,re.search("\Aabc","alexabc") 是匹配不到的 '\Z' 匹配字符结尾,同$ '\d' 匹配数字0-9 '\D' 匹配非数字 '\w' 匹配[A-Za-z0-9] '\W' 匹配非[A-Za-z0-9] 's' 匹配空白字符、\t、\n、\r , re.search("\s+","ab\tc1\n3").group() 结果 '\t' '(?P<name>...)' 分组匹配 re.search("(?P<province>[0-9]{4})(?P<city>[0-9]{2})(?P<birthday>[0-9]{4})","371481199306143242").groupdict("city") 结果{'province': '3714', 'city': '81', 'birthday': '1993'}
三、常用方法
1、re.compile(pattern,flags = 0 )
将正则表达式模式编译为正则表达式对象,可使用match(),search()以及下面所述的其他方法将其用于匹配
#Author:Anliu import re #res = re.match("^Chen","Chenrunrun123") #print(res) #print(res.group()) prog = re.compile('\d{2}') #定义正则对象,(匹配两个数字) print(prog.search("12bbc").group()) #通过调用group()方法得到匹配的字符串,如果字符串没有匹配。则返回None、 print(prog.search("wwww.123.com").group())
2、re.search(pattern,string,flags = 0 )
扫描字符串以查找正则表达式模式产生匹配项的第一个位置 ,然后返回相应的match对象。None
如果字符串中没有位置与模式匹配,则返回;否则返回false。请注意,这与在字符串中的某个点找到零长度匹配不同。
#在字符串中匹配 print(re.search('\w+','abcde').group()) print(re.search('a','bcdea').group())
3、re.match(pattern,string,flags = 0 )
如果字符串开头的零个或多个字符与正则表达式模式匹配,则返回相应的匹配对象。None如果字符串与模式不匹配,则返回;否则返回false。请注意,这与零长度匹配不同。
#Author:Anliu import re #同search,不过在字符串开始处进行了匹配,只会匹配一个对象 print(re.search('a','absabc').group()) print(re.match('a','absabc').group()) print(re.search('\D+','abc123com').group()) #非数字 print(re.match('\D+','abc123com').group()) print(re.search('\d+','abc123com').group()) #print(re.match('\d+','abc123com').group()) #match报错
4、re.fullmatch(pattern,string,flags = 0 )
如果整个字符串与正则表达式模式匹配,则返回相应的match对象。None如果字符串与模式不匹配,则返回;否则返回false。请注意,这与零长度匹配不同。
print(re.fullmatch('\w+',"abc123").group()) #print(re.fullmatch('abc','abcd').group()) #报错 print(re.fullmatch('abcd','abcd').group())
5、re.split(pattern,string,maxsplit = 0,flags = 0 )
通过出现模式来拆分字符串。如果在pattern中使用了捕获括号,那么模式中所有组的文本也将作为结果列表的一部分返回。如果maxsplit不为零,则最多会发生maxsplit分割,并将字符串的其余部分作为列表的最后一个元素返回。
print(re.split('[ab]','abcd')) #先按‘a’分割得到‘’和‘bcd’,在对‘’和‘bcd’分别按‘b’分割 print(re.split(r'\W+','Words,words,words.')) print(re.split(r'(\W+)','Words,words,words.')) print(re.split('[a-f]+','0a3B9',flags=re.IGNORECASE))
6、re.findall(pattern,string,flags = 0 )
以string列表形式返回string中pattern的所有非重叠匹配项。从左到右扫描该字符串,并以找到的顺序返回匹配项。如果该模式中存在一个或多个组,则返回一个组列表;否则,返回一个列表。如果模式包含多个组,则这将是一个元组列表。空匹配项包含在结果中。
print(re.findall('a','This is a tast from a!'))
结果:
['a', 'a', 'a']
7、re.finditer(pattern,string,flags = 0 )
返回一个迭代器,该迭代器在string类型的RE 模式的所有非重叠匹配中产生匹配对象。 从左到右扫描该字符串,并以找到的顺序返回匹配项。空匹配项包含在结果中。
a = re.finditer('[ab]','This is a tast from a!') #返回迭代器对象 for i in a: print(i.group())
8、re.sub(pattern,repl,string,count = 0,flags = 0 )
返回通过用替换repl替换字符串中最左边的不重叠模式所获得的字符串。如果找不到该模式, 则返回的字符串不变。 repl可以是字符串或函数;如果是字符串,则处理其中的任何反斜杠转义。即,将其转换为单个换行符,将其转换为回车,依此类推。count参数表示将匹配到的内容进行替换的次数。
print(re.sub('\d','S','abc12kkakla1wk21',2)) #将匹配到的数字替换成s,替换2个
9、re.subn(pattern,repl,string,count = 0,flags = 0 )
执行与相同的操作sub(),但返回一个元组。(new_string, number_of_subs_made)。
有的时候我们需要使用一些特殊符号如”$ * . ^”等的原意,有时候需要被转义后的功能,并且转义字符地使用很繁琐,容易出错。
re.escape(pattern) 可以对字符串中所有可能被解释为正则运算符的字符进行转义的应用函数。如果字符串很长且包含很多特殊技字符,而你又不想输入一大堆反斜杠,或者字符串来自于用户(比如通过raw_input函数获取输入的内容),且要用作正则表达式的一部分的时候,可以使用这个函数。
print(re.escape('www.python.org')) print(re.findall(re.escape('w.py'),"jw.py w.py.f"))
结果:
www\.python\.org ['w.py', 'w.py']
四、实例
(1)查找"http://www.python.org"
中的python
并替换为java
#Author:Anliu import re line = "http://www.python.org" pat = "(?<=\.).+(?=\.)" patobj = re.compile(pat) print(re.search(pat,line)) print(re.search(patobj,line)) print(patobj.search(line)) ''' 函数re.search在给定字符串中查找第一个与指定pat匹配的子串,如果找到将返回MatchObject(结果为True),否则为None.(结果为False) 观察结果<re.Match object; span=(11, 17), match='python'>,发现MatchObject的匹配子串为'python',起始与终止位置为11,17 ''' line1 = re.sub(pat,'java',line) line2 = patobj.sub('java',line) print(line1) print(line2) ''' 函数re.match尝试在给定字符串开头查找与正则表达式匹配的子串,和re.search相似,如果找到这样的子串,返回MatchObject,否则返回None 另外,re.match在模式与字符串开头匹配时就返回True,而不要求与整个字符串匹配,如果要求完全匹配,需要在模式末尾加上$,从而将匹配检查延伸到整个字符串. '''
(2)找出以http协议开头的网址
#Author:Anliu import re #方法一 #line1 = "http://www.python.com" #line2 = "ftp://www.python.com" #pat = "^http.*" #patobj = re.compile(pat) ##print(re.search(patobj,line)) #print(patobj.search(line1)) #print(patobj.search(line2)) #方法二: line1 = "http://www.python.com" line2 = "ftp://www.python.com" pat = "http.*" patobj = re.compile(pat) print(patobj.match(line1)) print(patobj.match(line2))