python成长之路17——re

一、正则表达式

(1)数量词的贪婪模式与非贪婪模式

正则表达式通常用于在文本中查找匹配的字符串。Python里数量词默认是贪婪的(在少数语言里也可能是默认非贪婪),总是尝试匹配尽可能多的字 符;非贪婪的则相反,总是尝试匹配尽可能少的字符。例如:正则表达式”ab*”如果用于查找”abbbc”,将找到”abbb”。而如果使用非贪婪的数量 词”ab*?”,将找到”a”。

注:我们一般使用非贪婪模式来提取。

(2)反斜杠问题

与大多数编程语言相 同,正则表达式里使用”\”作为转义字符,这就可能造成反斜杠困扰。假如你需要匹配文本中的字符”\”,那么使用编程语言表示的正则表达式里将需要4个反 斜杠”\\\\”:前两个和后两个分别用于在编程语言里转义成反斜杠,转换成两个反斜杠后再在正则表达式里转义成一个反斜杠。

Python里的原生字符串很好地解决了这个问题,这个例子中的正则表达式可以使用r”\\”表示。同样,匹配一个数字的”\\d”可以写成r”\d”。有了原生字符串,妈妈也不用担心是不是漏写了反斜杠,写出来的表达式也更直观勒。

 

二、re

(1)re.match(正则表达式,原字符串,[参数])

 1 import re
 2 
 3 pattern = re.compile(r'hello',re.I)
 4   #re.I 忽略大小写
 5 res = re.match(pattern,'HelloHELLO')
 6 if res:
 7     print res.group()
 8 
 9 m=re.compile(r'(\w+) (\d+) (?P<zy>\W)(?P=zy)(\d+)')
10 res = re.match(m,"hello 123 !!234")
11 if res: #匹配成功为True
12     print res.group()
13 print res.string      #如果匹配成功的话,返回匹配时用到的文本
14 print res.re          #匹配时使用的Pattern对象
15 print m               #匹配时使用的Pattern对象
16 print res.pos         #正则表达式开始搜索的索引(不是开始匹配),索引是从0开始的
17 print res.endpos      #正则表达式结束搜索的索引(不是结束匹配)
18 print res.lastindex   #正则表达式最后一个匹配分组"()"的编号,字符串从前往后一个"()"是一个分组,
19                       # 分组是从第一个分组开始的,使用分组别名"(?P=zy)"的不算一个分组
20                       # 分组别名"(?P=zy)"和分组编号"(\1)"必须匹配这个别名和编号之前匹配到的
21                       # 字符串,eg:之前匹配到的是"a12",那这个别名或者编号就必须是匹配"a12"
22 print res.lastgroup   #同上,这个是最后一个匹配分组"()"的别名,最后一个分组没有别名则为None
23 print res.group(1,2)  #打印第一个和第二个分组
24 print res.groups()    #打印所有分组
25 print res.groupdict() #如果分组有别名,会将这个分组的别名作为key,分组匹配到的字符串作为value组成个dict
26 print res.start(2)    #第二个分组匹配开始的索引
27 print res.end(2)      #第二个分组匹配结束的索引
28 print res.span(2)     #(start,end)组成的元祖
29 print res.expand(r'\2 \3\1')  #以"分组2 分组3分组1"的格式输出
30 
31 执行结果:
32 hello 123 !!234
33 hello 123 !!234$#fd
34 <_sre.SRE_Pattern object at 0x106e00840>
35 <_sre.SRE_Pattern object at 0x106e00840>
36 0
37 19
38 4
39 None
40 ('hello', '123')
41 ('hello', '123', '!', '234')
42 {'zy': '!'}
43 6
44 9
45 (6, 9)
46 123 !hello
re.match
(2)re.search:
参数,属性和方法同re.match
 
区别是:
re.match是从string头开始匹配的,如果string头不匹配则返回None,而re.search会扫描整个string查找匹配
(3)re.split(正则表达式,原字符串,[参数]):
将匹配到的字符串作为分隔符对字符串进行分隔,最后一个参数是最大分隔次数,如果不写,默认全部分隔
1 m = re.compile(r'\d+')
2 res = re.split(m,"one1two2ten10three3four4")
3 print res
4 res2 = re.split(m,"one1two2ten10three3four4",2)
5 print res2
6 
7 执行结果:
8 ['one', 'two', 'ten', 'three', 'four', '']
9 ['one', 'two', 'ten10three3four4’]
re.split

(4)re.findall(正则表达式,原字符串,[参数]):

以列表形式返回全部能匹配的子串
1 m = re.compile(r'(\w+) (\d+)')
2 res = re.findall(m,"@#qw 123 ! !876tw 345^")
3 print res
4 
5 执行结果:
6 [('qw', '123'), ('876tw', '345’)]
re.findall

(5)re.finditer(正则表达式,原字符串,[参数]):

返回一个匹配子串的迭代器
 1 m = re.compile(r'(\w+) (\d+)')
 2 res = re.finditer(m,"@#qw 123 ! !876tw 345^")
 3     #返回一个匹配结果的迭代器
 4 print res
 5 for i in res:
 6     print i.group()
 7 
 8 执行结果:
 9 <callable-iterator object at 0x10f1083d0>
10 qw 123
11 876tw 345
re.finditer

(6)re.sub(正则表达式,替换字符串,原字符串,最多替换次数):

 1 m = re.compile(r'(\w+) (\w+) ')
 2 s = "1qa 2ws 3ed fr4 "
 3 print "原str:",s
 4 res = re.sub(m,r'123 abc',s)
 5 print "res:",res
 6 res1 =re.sub(m,r'\2 \1',s)
 7 print "res1:",res1
 8 
 9 def func(m):
10     return "i am group1:" + m.group(1) + "\ni am group2:" + m.group(2) + "\n"
11 res = re.sub(m,func,s)
12 print res
13 
14 执行结果:
15 原str: 1qa 2ws 3ed fr4 
16 res: 123 abc123 abc
17 res1: 2ws 1qafr4 3ed
18 i am group1:1qa
19 i am group2:2ws
20 i am group1:3ed
21 i am group2:fr4
re.sub

(7)re.subn(正则表达式,替换字符串,原字符串,最多替换次数)

用法功能同re.sub
区别是:
re.sub返回的是字符串
re.subn返回的是元祖:(替换后字符串,替换次数)
 1 m = re.compile(r'(\w+) (\w+) ')
 2 s = "1qa 2ws 3ed fr4 "
 3 print "原str:",s
 4 res = re.subn(m,r'123 abc',s)
 5 print "res:",res
 6 res1 =re.subn(m,r'\2 \1',s)
 7 print "res1:",res1
 8 
 9 def func(m):
10     return "i am group1:" + m.group(1) + "\ni am group2:" + m.group(2) + "\n"
11 res = re.subn(m,func,s)
12 print res
13 
14 执行结果:
15 原str: 1qa 2ws 3ed fr4 
16 res: ('123 abc123 abc', 2)
17 res1: ('2ws 1qafr4 3ed', 2)
18 ('i am group1:1qa\ni am group2:2ws\ni am group1:3ed\ni am group2:fr4\n', 2)
re.subn

 

posted @ 2017-03-27 11:04  meitangyanyan  阅读(203)  评论(0编辑  收藏  举报