Python正则表达式

正则表达式是个魔鬼,也是个天使。在你没有掌握它之前,它是魔鬼,在你掌握它后,它是天使,但是,时 不时还是要跳出来,给你调皮捣蛋一番。


一个正则表达式就是由普通字符以及特殊字符组成的文字模式,该模式描述在查找文字主体时待 匹配的一个或多个字符串。正则表达式作为一个模板,将某个字符模式与所搜索的字符串进行匹配,并能提取出匹配的结果。它是搜索、替换和解析复杂字符模式的 一种强大而标准的方法。

正则表达式有着总体规范的一套语法,但是到了各种语言中,又会有使用上的稍微不同,主要是表达式的细 微语法表达,还有语言的匹配类和方法的不同。

Python的所有类库都在re包中,和java 1.4以后的不同,String的各个方法,find和replace都不自做主张的去使用正则表达式,而是使用简单的字符串方式。这点我比较欣赏,有时 候只是做一些简单的替换,不要弄正则表达式这么麻烦,也让新手们摸不着北,替换两个字符就要去了解正则表达式这么夸张。

工具

    Python有一个非常好的正则表达式辅助调试工具:Kodos。有Windows版本,提供了对正则表达式的方便的实时调试功能,建议学习正则表达式前 一定要下载:
     http://kodos.sourceforge.net/       

应用场景: 

  1.  转换url为路径名
import   re

articleUrl = "http://pp.sohu.com/yule/photoview-44789795.html#44789795"
path = re.sub("http://|https://", "", articleUrl)
path = re.sub("[?&.=#-]", "_", path)

path
    'pp_sohu_com/yule/photoview_44789795_html_44789795'
 

   
       采用这种替换方式,随时发现url中有新非法字符,添加到[]中就可以了。[]表示字符集,在[]其中的任意字符,都会被匹配到
       

  2.  提取html页面中img标签的src属性 

      import   re
    
  import   urllib

    imgSrcPattern 
  =   r  '''  <img/s*src/s*="?(/S+)"?  ''' 
    
    pageUrl 
  =     '  http://pp.sohu.com/yule/photoview-44789795.html#44789795  ' 
    usock 
  =   urllib.urlopen(pageUrl)
    s 
  =   usock.read()        
    usock.close()

    imgSrcs 
  =   re.findall(imgSrcPattern, s)
    imgSrcs
        ['http://js.pp.sohu.com/ppp/pp2/style/images/logo.gif"', 'http://js.pp.sohu.com/ppp/pp2/style/images/both.gif"']
 


       这个img的src模式是清风写的,借用一下。很方便的就把一个很大的html页面字符串,匹配出所有的img的src属性了


Python 用法:

  • 正则对象(re object)
    • search():  最常用的,返回一个匹配对象(Match Object)
    • match():类似search,但仅仅从文字的开始进行匹配;
    • split():分割一个string,返回字符串的数组
    • findall():找到所有的匹配字符串的清单(list)
    • finditer():类似findall,返回匹配对象(Match Object)的iteration
    • sub(): 字符串替换
    • subn(): 类似sub, 但是同时返回替换的数量
  • re是个非常强大的对象,很多功能,根本不用调用其它 类和方法,re的一个方法就搞定了,充分体现python小巧灵活的特点。
  • sub和subn都可以加上一个替换个数的参数,指定 替换多少个match,0为全部替换

  •          imgSrcPattern   =   r  '''  <img/s*src/s*="?(/S+)"?  ''' 
             imgSrcs 
      =   re.findall(imgSrcPattern, s)


  • 编译对象(compile object)

        编译的好处是提高速度,如果一个固定正则表达式将会被反复调用多次,那么先compile之后再用,将能够提高效率。
        
        它的接口和re基本一模一样,就是不用加正则表达式的pattern参数了。

       
        compile_obj   =   re.compile(  "  [?&.=#-]  "  )
        compile_obj.sub(matchText, 
  "  _  "  )


  • 匹配对象(match Object): 匹配的结果
    • group(): 得到匹配的字符串组。这个函数非常灵活,可传递组的编号、范围、名字等。
    • start(), end(), span(): 匹配字符串的起始、中止、范围
    • groups(): 返回所有的子组

        注意,无论match还是search,都是得到一个match对象而已,如果要获得所有的match对象,必须使用finditer方法,获得一个 match对象集合        的iteration,然后遍历,获得单独的match对象,再调用上述的方法。

      
       compile_obj   =   re.compile(pattern)
       match_obj 
  =   compile_obj.search(matchstr)
       all_groups 
  =   match_obj.groups() 
       group_1 
  =   match_obj.group(  1  )
       src 
  =   match_obj.group(  '  src  '  )


难点:

     1。组(Group)
        
        组或者不是每种支持正则表达式的语言都支持的,或者说,即便支持,语法区别也很大,暂时没研究其它语言的,稍后研究一下java,不过可以确定java也 是支持组,只不过好像不支持组的命名。

        Python的组支持很好,基本的组模式当然都支持,组的命名功能很强大。

        (?P<name>...) 
            例如(?P<id>[a-zA-Z_]/w*),这样,所有匹配[a-zA-Z_]和/w*的对象就会被匹配到,然后存在以id为名的 group里面,可以通过match对象的m.group('id')或者m.group(1)获得。
            
        (?P=name) 
            等于是对name匹配结果的引用,提供了一定程度上的动态正则表达式功能。
            
            例如(?P<id>[a-zA-Z_]/w*)........(?P=id),在第一个匹配结果中,id的结果是John,正则表达式就变 成了
                (?P<id>[a-zA-Z_]/w*)........John
            第二个匹配结果,id为Andy,那么正则表达式就变成了
                (?P<id>[a-zA-Z_]/w*)........Andy

    2。贪婪(Greedy) 
        对数量词(*,?,+)的一个限制,如果没有加上?限制修饰符号,那么就会尽可能多的匹配字符

        <H1>title</H1>

        <.*>会匹配<H1>title</H1>,而<.*?>只会匹配<H1>,其实两种匹 配结果都是合理的,关键就是加上?后,结果就是最小匹配值,而不加的话,默认就是最大匹配值

基本语法: 
    
    () 
       
     []
 
       用来表示一组字符集,常用模式。字符可以单独列出,或者用"-"分开两个字符,表示一个范围内的字符集。
       特殊字符在字符集内无效。例如
            [akm$],就会匹配任何"a", "k", "m", 或者 "$"
            [a-z]就会匹配所有的小写字母
            [a-zA-Z0-9]就会匹配任何字母或者数字

       字符类型在字符集内有效,例如/w或者/S
       如果要匹配]和-字符,或者用/处理,或者放在第一位

     ^ 
       很常见的符号,两种含义。
       在[]外表示要求匹配字符串的开始,和$刚好相反。在[]内表示排除所有匹配到的结果,不过一定要放在第一位,否则就是一个普通字符了。
     
       ^abc.*abc$:   表示匹配以abc开头,由以abc结束的字符串

     {} 
            长度修饰符
            {n,m}    表示长度在n-m之间
            {m}     等于{0,m}
    
             *         {0, n}
             ?         {0, 1}
             +         {1, n}
           
     . 
        任意字符
            
    
     / 
       转义字符,对于很多的特殊符号,例如:/,[,],^,",如果要匹配原来的文字,都要用/表示转义。但是对于下面的特殊字符,则有不同意思。
       这些特殊的预定义字符,都要和文字或者数量词搭配。例如

       /d*    表示任意长度的数字
       /S*    表示任意长度的非空字母      

        /A 
        匹配字符串开始

        /Z
        匹配字符串结束 
        
        /b 
        匹配在开头和结尾的空白的空字符串

        /B 
        匹配不在开头或者结尾的空白字符串

        /d 
        匹配数字[0-9]
         
        /D 
        匹配非数字[^0-9]

        /s 
        匹配空白字符 

        /S 
        匹配非空白字符 

        /w 
        匹配字母和数字

        /W 
        匹配非字母和数字


参考网站: 
     Python手册
         http://docs.python.org/lib/module-re.html

     Dive Into Python
         http://diveintopython.org/regular_expressions/index.html

     Python手册
         http://docs.python.org/lib/module-re.html

     潘俊勇的Blog
        http://czug.org/blog/panjy/python-rx

     清风练习贴
         http://www.javaeye.com/article/10115

转自:http://blog.csdn.net/suofiya2008/article/details/5577961


1. 正则表达式基础

1.1. 简单介绍

正则表达式并不是Python的一部分。正则表达式是用于处理字符串的强大工具,拥有自己独特的语法以及一个独立的处理引擎,效率上可能不如str自带的方法,但功能十分强大。得益于这一点,在提供了正则表达式的语言里,正则表达式的语法都是一样的,区别只在于不同的编程语言实现支持的语法数量不同;但不用担心,不被支持的语法通常是不常用的部分。如果已经在其他语言里使用过正则表达式,只需要简单看一看就可以上手了。

下图展示了使用正则表达式进行匹配的流程: 
Python正则表达式_第1张图片

正则表达式的大致匹配过程是:依次拿出表达式和文本中的字符比较,如果每一个字符都能匹配,则匹配成功;一旦有匹配不成功的字符则匹配失败。如果表达式中有量词或边界,这个过程会稍微有一些不同,但也是很好理解的,看下图中的示例以及自己多使用几次就能明白。

下图列出了Python支持的正则表达式元字符和语法:   
Python正则表达式_第2张图片

1.2. 数量词的贪婪模式与非贪婪模式

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

1.3. 反斜杠的困扰

与大多数编程语言相同,正则表达式里使用"/"作为转义字符,这就可能造成反斜杠困扰。假如你需要匹配文本中的字符"/",那么使用编程语言表示的正则表达式里将需要4个反斜杠"////":前两个和后两个分别用于在编程语言里转义成反斜杠,转换成两个反斜杠后再在正则表达式里转义成一个反斜杠。Python里的原生字符串很好地解决了这个问题,这个例子中的正则表达式可以使用r"//"表示。同样,匹配一个数字的"//d"可以写成r"/d"。有了原生字符串,你再也不用担心是不是漏写了反斜杠,写出来的表达式也更直观。

1.4. 匹配模式

正则表达式提供了一些可用的匹配模式,比如忽略大小写、多行匹配等,这部分内容将在Pattern类的工厂方法re.compile(pattern[, flags])中一起介绍。

转自: http://blog.csdn.net/lrjnlp/article/details/6061057

你可能感兴趣的:(python,正则表达式,object,search,语言,Path)