python正则表达式-深入浅出(共16页).doc
《python正则表达式-深入浅出(共16页).doc》由会员分享,可在线阅读,更多相关《python正则表达式-深入浅出(共16页).doc(16页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、精选优质文档-倾情为你奉上python的正则表达式 re延伸阅读:python的 内建函数 和 subprocess 。此文是本系列的第三篇文章了,和之前一样,内容出自官方文档,但是会有自己的理解,并非单纯的翻译。所以,如果我理解有误,欢迎指正,谢谢。本模块提供了和Perl里的正则表达式类似的功能,不关是正则表达式本身还是被搜索的字符串,都可以是Unicode字符,这点不用担心,python会处理地和Ascii字符一样漂亮。正则表达式使用反斜杆()来转义特殊字符,使其可以匹配字符本身,而不是指定其他特殊的含义。这可能会和python字面意义上的字符串转义相冲突,这也许有些令人费解。比如,要匹配
2、一个反斜杆本身,你也许要用来做为正则表达式的字符串,因为正则表达式要是,而字符串里,每个反斜杆都要写成。你也可以在字符串前加上 r 这个前缀来避免部分疑惑,因为 r 开头的python字符串是 raw 字符串,所以里面的所有字符都不会被转义,比如rn这个字符串就是一个反斜杆加上一字母n,而n我们知道这是个换行符。因此,上面的你也可以写成r,这样,应该就好理解很多了。可以看下面这段: import re s = x5c #0x5c就是反斜杆 print s re.match(, s) #这样可以匹配 re.match(r, s) #这样也可以 re.match(, s) #但是这样不行Trace
3、back (most recent call last): File , line 1, in File /usr/lib/python2.6/re.py, line 137, in match return _compile(pattern, flags).match(string) File /usr/lib/python2.6/re.py, line 245, in _compile raise error, v # invalid expressionsre_constants.error: bogus escape (end of line)另外值得一提的是,re模块的方法,大多也就
4、是RegexObject对象的方法,两者的区别在于执行效率。这个在最后再展开吧。正则表达式语法正则表达式(RE)指定一个与之匹配的字符集合;本模块所提供的函数,将可以用来检查所给的字符串是否与指定的正则表达式匹配。正则表达式可以被连接,从而形成新的正则表达式;例如A和B都是正则表达式,那么AB也是正则表达式。一般地,如果字符串p与A匹配,q与B匹配的话,那么字符串pq也会与AB匹配,但A或者B里含有边界限定条件或者命名组操作的情况除外。也就是说,复杂的正则表达式可以用简单的连接而成。正则表达式可以包含特殊字符和普通字符,大部分字符比如A,a和0都是普通字符,如果做为正则表达式,它们将匹配它们本
5、身。由于正则表达式可以连接,所以连接多个普通字符而成的正则表达式last也将匹配last。(后面将用不带引号的表示正则表达式,带引号的表示字符串)下面就来介绍正则表达式的特殊字符:.点号,在普通模式,它匹配除换行符外的任意一个字符;如果指定了 DOTALL 标记,匹配包括换行符以内的任意一个字符。尖尖号,匹配一个字符串的开始,在 MULTILINE 模式下,也将匹配任意一个新行的开始。$美元符号,匹配一个字符串的结尾或者字符串最后面的换行符,在 MULTILINE 模式下,也匹配任意一行的行尾。也就是说,普通模式下,foo.$去搜索foo1nfoo2n只会找到foo2,但是在 MULTILIN
6、E 模式,还能找到 foo1,而且就用一个 $ 去搜索foon的话,会找到两个空的匹配:一个是最后的换行符,一个是字符串的结尾,演示: re.findall(foo.$), foo1nfoo2n)foo2 re.findall(foo.$), foo1nfoo2n, re.MULTILINE)foo1, foo2 re.findall($), foon), *星号,指定将前面的RE重复0次或者任意多次,而且总是试图尽量多次地匹配。+加号,指定将前面的RE重复1次或者任意多次,而且总是试图尽量多次地匹配。?问号,指定将前面的RE重复0次或者1次,如果有的话,也尽量匹配1次。*?, +?, ?从前
7、面的描述可以看到*,+和?都是贪婪的,但这也许并不是我们说要的,所以,可以在后面加个问号,将策略改为非贪婪,只匹配尽量少的RE。示例,体会两者的区别: re.findall(, title)H1title re.findall(, title)H1, /H1mm是一个数字,指定将前面的RE重复m次。m,nm和n都是数字,指定将前面的RE重复m到n次,例如a3,5匹配3到5个连续的a。注意,如果省略m,将匹配0到n个前面的RE;如果省略n,将匹配n到无穷多个前面的RE;当然中间的逗号是不能省略的,不然就变成前面那种形式了。m,n?前面说的m,n,也是贪婪的,a3,5如果有5个以上连续a的话,会匹
8、配5个,这个也可以通过加问号改变。a3,5?如果可能的话,将只匹配3个a。反斜杆,转义*,?等特殊字符,或者指定一个特殊序列(下面会详述)由于之前所述的原因,强烈建议用raw字符串来表述正则。方括号,用于指定一个字符的集合。可以单独列出字符,也可以用-连接起止字符以表示一个范围。特殊字符在中括号里将失效,比如akm$就表示字符a,k,m,或$,在这里$也变身为普通字符了。a-z匹配任意一个小写字母,a-zA-Z0-9匹配任意一个字母或数字。如果你要匹配或-本身,你需要加反斜杆转义,或者是将其置于中括号的最前面,比如可以匹配你还可以对一个字符集合取反,以匹配任意不在这个字符集合里的字符,取反操作
9、用一个放在集合的最前面表示,放在其他地方的将不会起特殊作用。例如5将匹配任意不是5的字符;将匹配任意不是的字符。注意:在中括号里,+、*、(、)这类字符将会失去特殊含义,仅作为普通字符。反向引用也不能在中括号内使用。|管道符号,A和B是任意的RE,那么A|B就是匹配A或者B的一个新的RE。任意个数的RE都可以像这样用管道符号间隔连接起来。这种形式可以被用于组中(后面将详述)。对于目标字符串,被|分割的RE将自左至右一一被测试,一旦有一个测试成功,后面的将不再被测试,即使后面的RE可能可以匹配更长的串,换句话说,|操作符是非贪婪的。要匹配字面意义上的|,可以用反斜杆转义:|,或是包含在反括号内:
10、|。(.)匹配圆括号里的RE匹配的内容,并指定组的开始和结束位置。组里面的内容可以被提取,也可以采用number这样的特殊序列,被用于后续的匹配。要匹配字面意义上的(和),可以用反斜杆转义:(、),或是包含在反括号内:(、)。(?.)这是一个表达式的扩展符号。?后的第一个字母决定了整个表达式的语法和含义,除了(?P.)以外,表达式不会产生一个新的组。下面介绍几个目前已被支持的扩展:(?iLmsux)i、L、m、s、u、x里的一个或多个字母。表达式不匹配任何字符,但是指定相应的标志:re.I(忽略大小写)、re.L(依赖locale)、re.M(多行模式)、re.S(.匹配所有字符)、re.U(
11、依赖Unicode)、re.X(详细模式)。关于各个模式的区别,下面会有专门的一节来介绍的。使用这个语法可以代替在pile()的时候或者调用的时候指定flag参数。例如,上面举过的例子,可以改写成这样(和指定了re.MULTILINE是一样的效果): re.findall(?m)(foo.$), foo1nfoo2n)foo1, foo2另外,还要注意(?x)标志如果有的话,要放在最前面。(?:.)匹配内部的RE所匹配的内容,但是不建立组。(?P.)和普通的圆括号类似,但是子串匹配到的内容将可以用命名的name参数来提取。组的name必须是有效的python标识符,而且在本表达式内不重名。命名
12、了的组和普通组一样,也用数字来提取,也就是说名字只是个额外的属性。演示一下: m=re.match(?Pa-zA-Z_w*), abc=123) m.group(var)abc m.group(1)abc(?P=name)匹配之前以name命名的组里的内容。演示一下: re.match(?Pw*).*, xxx) #这个不匹配 re.match(?Pw*).*, xxx) #这个匹配(?#.)注释,圆括号里的内容会被忽略。(?=.)如果 . 匹配接下来的字符,才算匹配,但是并不会消耗任何被匹配的字符。例如 Isaac (?=Asimov) 只会匹配后面跟着 Asimov 的 Isaac ,这个
13、叫做“前瞻断言”。(?!.)和上面的相反,只匹配接下来的字符串不匹配 . 的串,这叫做“反前瞻断言”。(?=.)只有当当前位置之前的字符串匹配 . ,整个匹配才有效,这叫“后顾断言”。(? m = re.search(? m.group(0)egg(?!.)同理,这个叫做“反后顾断言”,子RE需要固定长度的,含义是前面的字符串不匹配 . 整个才算匹配。(?(id/name)yes-pattern|no-pattern)如有由id或者name指定的组存在的话,将会匹配yes-pattern,否则将会匹配no-pattern,通常情况下no-pattern也可以省略。例如:()可以匹配 和 use
14、r,但是不会匹配 unistr = uu2076u2084abc print unistrabc print re.findall(d+, unistr, re.U)0D和d相反,不多说了。s当未指定UNICODE和LOCALE这两个标志位时,匹配任何空白字符,等效于 tnrfv。如果指定了LOCALE,则还要加LOCALE相关的空白字符;如果指定了UNICODE,还要加上UNICODE空白字符,如较常见的空宽度连接空格(uFEFF)、零宽度非连接空格(u200B)等。S和s相反,也不多说。w当未指定UNICODE和LOCALE这两个标志位时,等效于a-zA-Z0-9_。当指定了LOCALE时
15、,为0-9_加上当前LOCAL指定的字母。当指定了UNICODE时,为0-9_加上UNICODE库里的所有字母。W和w相反,不多说。Z只匹配字符串的结尾。匹配之于搜索python提供了两种基于正则表达式的操作:匹配(match)从字符串的开始检查字符串是否个正则匹配。而搜索(search)检查字符串任意位置是否有匹配的子串(perl默认就是如此)。注意,即使search的正则以开头,match和search也还是有许多不同的。 re.match(c, abcdef) # 不匹配 re.search(c, abcdef) # 匹配模块的属性和方法pile(pattern, flags)把一个正则
16、表达式pattern编译成正则对象,以便可以用正则对象的match和search方法。得到的正则对象的行为(也就是模式)可以用flags来指定,值可以由几个下面的值OR得到。以下两段内容在语法上是等效的:prog = pile(pattern)result = prog.match(string)result = re.match(pattern, string)区别是,用了pile以后,正则对象会得到保留,这样在需要多次运用这个正则对象的时候,效率会有较大的提升。再用上面用过的例子来演示一下,用相同的正则匹配相同的字符串,执行100万次,就体现出compile的效率了(数据来自我那1.86G
17、 CPU的神舟本本): timeit.timeit(. setup=import re; reg = pile(?Pw*).*),. stmt=reg.match(xxx),. number=)1.51562 timeit.timeit(. setup=import re,. stmt=re.match(?Pw*).*, xxx),. number=)4.02197re.Ire.IGNORECASE让正则表达式忽略大小写,这样一来,A-Z也可以匹配小写字母了。此特性和locale无关。re.Lre.LOCALE让w、W、b、B、s和S依赖当前的locale。re.Mre.MULTILINE影响
18、和$的行为,指定了以后,会增加匹配每行的开始(也就是换行符后的位置);$会增加匹配每行的结束(也就是换行符前的位置)。re.Sre.DOTALL影响.的行为,平时.匹配除换行符以外的所有字符,指定了本标志以后,也可以匹配换行符。re.Ure.UNICODE让w、W、b、B、d、D、s和S依赖Unicode库。re.Xre.VERBOSE运用这个标志,你可以写出可读性更好的正则表达式:除了在方括号内的和被反斜杠转义的以外的所有空白字符,都将被忽略,而且每行中,一个正常的井号后的所有字符也被忽略,这样就可以方便地在正则表达式内部写注释了。也就是说,下面两个正则表达式是等效的:a = pile(rd
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- python 正则 表达式 深入浅出 16
限制150内