《python正则表达式模块re讲解》由会员分享,可在线阅读,更多相关《python正则表达式模块re讲解(7页珍藏版)》请在金锄头文库上搜索。
1、第 1 页 共 7 页2 re 模块的基本函数在上面的说明中,我们已经对 re 模块的基本函数 findall很熟悉了。当然如果光有 findall 的话,很多功能是不能实现的。下面开始介 绍一下 re 模块其它的常用基本函数。灵活搭配使用这些函数,才能充分发挥 Python 正则式的 强大功能。首先还是说下老熟人 findall 函数吧findall(rule , target ,flag )在目标字符串中查找符合规则的字符串。第一个参数是规则,第二个参数是目 标字符串,后面 还可以跟一个 规则选项(选项功能将在compile 函数的说明中详细说明)。返回结果结果是一个列表,中间 存放的是符
2、合规则的字符串。如果没有符合规则的字符串被找到,就返回一个空列表。2.1 使用 compile 加速compile( rule ,flag )将正则规则编译成一个 Pattern 对象,以供接下来使用。第一个参数是规则式,第二个参数是 规则选项。返回一个 Pattern 对象直接使用 findall ( rule , target )的方式来匹配字符串,一次两次没什么,如果是多次使用的 话,由于正则引擎每次都要把规则解释一遍,而规则的解释又是相当 费时间的,所以 这样的效率就很低了。如果要多次使用同一规则 来进行匹配的话,可以使用 pile 函数来将规则预编译,使用编译过返回的 Regular
3、 Expression Object 或叫做 Pattern 对象来进行查找。 s=111,222,aaa,bbb,ccc333,444ddd rule=rbd+b compiled_rule=pile(rule) compiled_rule.findall(s)111, 222可见使用 compile 过的规则使用和未编译的使用很相似。compile 函数还可以指定一些规则标志,来指定一些特殊选项。多个 选项之间用 |(位或)连接起来。I IGNORECASE 忽略大小写区别。L LOCAL 字符集本地化。这个功能是为了支持多语言版本的字符集使用环境的,比如在转义符w,在英文环境下,它代表a
4、-zA-Z0-9 ,即所以英文字符和数字。如果在一个法语环境下使用,缺省设置下,不能匹配 或 。加上这 L 选项和就可以匹配了。不过这个对于中文环境似乎没有什么用,它仍然不能匹配中文字符。M MULTILINE 多行匹配。在这个模式下(代表字符串开 头) 和$(代表字符串结尾) 将能够匹配多行的情况,成为行首和行尾 标记。比如 s=123 456n789 012n345 678 rc=pile(rd+) #匹配一个位于开 头的数字,没有使用 M 选项 rc.findall(s)123 #结果只能找到位于第一个行首的123 rcm=pile(rd+,re.M) #使用 M 选项 rcm.find
5、all(s)123, 789, 345 #找到了三个行首的数字第 2 页 共 7 页同样, 对于$来 说,没有使用 M 选项,它将匹配最后一个行尾的数字,即678,加上以后,就能匹配三个行尾的数字 456 012 和 678 了. rc=pile(rd+$) rcm=pile(rd+$,re.M) rc.findall(s)678 rcm.findall(s)456, 012, 678S DOTALL .号将匹配所有的字符。缺省情况下 .匹配除换行符n外的所有字符,使用这一选项以后,. 就能匹配包括n的任何字符了。U UNICODE w, W, b, B, d, D, s 和 S 都将使用 U
6、nicode。X VERBOSE 这个选项忽略规则表达式中的空白,并允许使用#来引导一个注释。这样可以让你把规则写得更美观些。比如你可以把 规则 rc = pile(rd+|a-zA-Z+) #匹配一个数字或者单词使用 X 选项写成: rc = pile(r # start a ruled+ # number| a-zA-Z+ # word, re.VERBOSE)在这个模式下,如果你想匹配一个空格,你必须用 的形式(后面跟一个空格) 2.2 match 与 searchmatch( rule , targetString ,flag )search( rule , targetString
7、,flag )(注:re 的 match 与 search 函数同 compile 过的 Pattern 对象的 match 与 search 函数的参数是不一样的。 Pattern 对象的 match 与 search 函数更为强大,是真正最常用的函数)按照规则在目标字符串中进行匹配。第一个参数是正则规则,第二个是目 标字符串,第三个是 选项 (同 compile 函数的选项)返回:若成功返回一个 Match 对象,失败无返回findall 虽然很直 观,但是在 进行更复杂的操作时,就有些力不从心了。此时更多的使用的是match 和 search 函数。他们的参数和 findall 是一样的
8、,都是:match( rule , targetString ,flag )search( rule , targetString ,flag )不过它们的返回不是一个简单的字符串列表,而是一个 MatchObject (如果匹配成功的话).。通过操作这个 matchObject,我 们可以得到更多的信息。需要注意的是,如果匹配不成功,它们则返回一个 NoneType。所以在对匹配完的结果进行操作之前,你必需先判断一下是否匹配成功了,比如: m=re.match( rule , target ) if m: #必需先判断是否成功doSomethin第 3 页 共 7 页这两个函数唯一的区别是:
9、match 从字符串的开头开始匹配,如果开头位置没有匹配成功,就算失败了;而 search 会跳过开头, 继续向后寻找是否有匹配的字符串。针对不同的需要,可以灵活使用这两个函数。关于 match 返回的 MatchObject 如果使用的问题,是 Python 正则式的精髓所在,它与组的使用密切相关。我将在下一部分详细讲 解, 这里只举个最简单的例子:例: s= Tom:9527 , Sharry:0003 m=re.match( r(?Pw+):(?Pd+) , s ) m.group()Tom:9527 m.groups()(Tom, 9527) m.group(name)Tom m.gr
10、oup(num)95272.3 finditerfinditer( rule , target ,flag )参数同 findall返回一个迭代器finditer 函数和 findall 函数的区别是,findall 返回所有匹配的字符串,并存为一个列表,而finditer 则 并不直接返回这些字符串,而是返回一个迭代器。关于迭代器,解 释起来有点复杂, 还是看看例子把: s=111 222 333 444 for i in re.finditer(rd+ , s ):print i.group(),i.span() #打印每次得到的字符串和起始结束位置结果是111 (0, 3)222 (4,
11、 7)333 (8, 11)444 (12, 15)简单的说吧,就是 finditer 返回了一个可调用的对象,使用 for i in finditer()的形式,可以一个一个的得到匹配返回的 Match 对象。这在对每次返回的对象进行比 较复杂的操作时比较有用。2.4 字符串的替 换和修改re 模 块还 提供了对字符串的替换和修改函数,他们比字符串对象提供的函数功能要强大一些。这几个函数是sub ( rule , replace , target ,count )subn(rule , replace , target ,count )在目标字符串中规格规则查找匹配的字符串,再把它 们替换成
12、指定的字符串。你可以指定一个最多替换次数,否则将替换所有的匹配到的字符串。第 4 页 共 7 页第一个参数是正则规则,第二个参数是指定的用来替 换的字符串,第三个参数是目标字符串,第四个参数是最多替换次数。这两个函数的唯一区别是返回值。sub 返回一个被替换的字符串sub 返回一个元组,第一个元素是被替 换的字符串,第二个元素是一个数字,表明 产生了多少次替换。例,将下面字符串中的dog 全部替换成cat s= I have a dog , you have a dog , he have a dog re.sub( rdog , cat , s ) I have a cat , you ha
13、ve a cat , he have a cat 如果我们只想替换前面两个,则 re.sub( rdog , cat , s , 2 ) I have a cat , you have a cat , he have a dog 或者我们想知道发生了多少次替换,则可以使用 subn re.subn( rdog , cat , s )( I have a cat , you have a cat , he have a cat , 3)split( rule , target ,maxsplit )切片函数。使用指定的正则规则 在目标字符串中查找匹配的字符串,用它们作为分界,把字符串切片。第一个
14、参数是正则规则,第二个参数是目 标字符串,第三个参数是最多切片次数返回一个被切完的子字符串的列表这个函数和 str 对象提供的 split 函数很相似。 举个例子,我们想把上例中的字符串被,分割开,同时 要去掉逗号前后的空格 s= I have a dog , you have a dog , he have a dog re.split( s*,s* , s ) I have a dog, you have a dog, he have a dog 结果很好。如果使用 str 对象的 split 函数,则由于我们不知道,两边会有多少个空格,而不得不对结果再进行一次处理。escape( string )这是个功能比较古怪的函数,它的作用是将字符串中的 non-alphanumerics 字符(我已不知道该怎么翻译比较好了)用反义字符的形式显示出来。有时候你可能希望在正 则式中匹配一个字符串,不过 里面含有很多 re 使用的符号,你要一个一个的修改写法 实在有点麻烦,你可以使用这个函数,例 在目标字符串 s 中匹配(*+?)这个子字符串 s= 111 222 (*+?) 333 rule= re.escape( r(*+?) ) print rule(*+?) re.findall( rule , s )(*+?)第