15.正则表达式

来源:互联网 发布:手机淘宝实名认证电话 编辑:程序博客网 时间:2024/06/05 14:35
----------------初识正则表达式----------------
(1)概念  

    正则表达式(Regular Expression)是搜索、替换和解析复杂字符串的一种强大而标准的方法。

    正则表达式是对字符串操作的一种逻辑公式,就是用事先定义好的一些特定字符、及这些特定字符的组合,组成一个“规则字符串”,
    
    这个“规则字符串”用来表达对字符串的一种过滤逻辑。


(2)作用

    给定一个正则表达式和另一个字符串,我们可以达到如下的目的:

    1. 给定的字符串是否符合正则表达式的过滤逻辑(称作“匹配”);
    2. 可以通过正则表达式,从字符串中获取我们想要的特定部分。

    由于正则表达式主要应用对象是文本,因此它在各种文本编辑器场合都有应用,小到著名编辑器 EditPlus,大到 Microsoft Word、

    Visual Studio 等大型编辑器,都可以使用正则表达式处理文本内容。



(3)组成元素

     正则表达式由一些普通字符和一些元字符组成。
  
     普通字符:大小写字母和数字;
     元字符:.  ^  $  *  +  ?  {}  []  \  |  ()
 
----------------元字符----------------

(1)[] 

     ——[^abc] 字符集合。匹配所包含的任意一个字符。
             例如,"[abc]" 可以匹配 "plain" 中的 "a"。


     ——[^abc] 负值字符集合。匹配未包含的任意字符。
             例如,"[^abc]" 可以匹配 "plain" 中的 "plin"。


     ——[a-z] 字符范围,匹配指定范围内的任意字符。
             例如,"[a-z]" 可以匹配 "a" 到 "z" 范围内的任意小写字符。


     ——[^a-z]  负值字符范围。匹配任何不在指定范围内的任意字符。
             例如,"[^a-z]" 可以匹配除了"a" 到 "z" 范围内的任意字符。

     注意:元字符在字符集中不起任何元字符的作用 ,作为普通字符对待。

(2).

     匹配除换行符外的任意一个字符

(3)^

     匹配行首。如果设置了 Multiline属性,^ 也匹配换行字符串中的每个换行。

(4)$

     匹配行尾。所谓“行尾”,也就是字符串尾部以及换行符之后的位置。

(5)\

     ——转义字符,只作用于下一个字符。用于让元字符表现的与普通字符一样的效果。
             例如,"\\n" 匹配 \n ;序列"\\" 匹配 "\" 而 "\(" 则匹配 "("。

     ——反斜杠后面加不同的字符以表示不同特殊意义。
             例如,"\n" 匹配换行符;
             例如,"\d" 匹配一个数字字符。等价于 [0-9] 。
             例如,"\D" 匹配一个非数字字符。等价于 [^0-9] 。
             例如,"\s" 匹配任何不可见字符,包括空格、制表符、换页符等等,等价于 [\f\n\r\t\v] 。
             例如,"\S" 匹配任何可见字符。等价于 [^\f\n\r\t\v] 。
             例如,"\w" 匹配任何字母数字字符。等价于 [a-zA-Z0-9] 。
             例如, "\W" 匹配任何非字母数字字符。等价于 [^a-zA-Z0-9] 。

(6)*

     ——指定前一个字符可以被匹配零次或更多次。匹配引擎会试着重复尽可能多的次数(不超过整数界定的范围,20亿)
             例如:"zo*" 可以匹配 "z" ,也能匹配 "zo" 以及 "zoo" 。
     —— * 等价于 {0,}

(7)+

     ——指定前一个字符可以被匹配一次或更多次。
             例如:"zo+" 可以匹配 "zo" 以及 "zoo",但不能匹配 "z" 。
     —— + 等价于 {1,}

(8)?

     ——被匹配零次或一次。
             例如,"zone?" 可以匹配 "zon" 以及 "zone" 。
     ——当该字符跟在任何一个其他限制符后面时,匹配模式是非贪婪的。非贪婪模式尽可能少的匹配所搜索的字符串,

             而默认的贪婪模式尽可能多的匹配所搜索的字符串。
             例如,对于字符串 "ooooo" , "o+?" 将匹配单个 "o" ,而 "o+" 将匹配所有 "o" 。

(9){n}、{n,}、{n,m}

    ——{n} n是一个非负整数,指定前一个字符可以被匹配n次。
            例如,"o{2}" 不能匹配 "Bob" 中的 "o" ,但是能匹配 "food" 中的两个o。

    ——{n,} n是一个非负整数,指定前一个字符字少匹配 n 次。
            例如,"o{2,}" 不能匹配 "Bob" 中的 "o" ,但是能匹配 "foooooood" 中的所有o。  "o{1,}" 等价于 "o+" ;"o{0,}" 等价于 "o*" 。
    ——{n,m} m 和 n 均为非负整数,其中 n≤m 。最少匹配 n 次且最多匹配 m 次。

            例如,"o{1,3}" 将匹配 "foooooood" 中的前三个o。o{0,1}" 等价于 "o?" 。
            注意:在逗号和两个数之间不能有空格!



----------------常用的正则表达式函数----------------

(1)在Python中使用正则表达式时,首先导入模块re。 
         即 >>>import re

(2)字符串前面加 "r" :禁止转义!反斜杠不会被任何特殊方式处理。

     例:
     >>> print("abc\n")     abc     >>> print("abc\\n")     abc\n     >>> print(r"abc\n")     abc\n     >>> print(r"abc\\n")     abc\\n

(3)re.findall(pattern,string) ——> list

         列出字符串中模式的所有匹配项,并作为一个列表返回。如果无匹配,则返回空列表。

     例:
     >>> import re     >>> s=r"abc"     >>> re.findall(s,"aabbccabdabcaabc")     ['abc', 'abc']

(4)re.compile(pattern,flags=0) ——> pattern object.

         根据包含正则表达式的字符串创建模式对象,可以实现更有效率地匹配。
         此外,re.cpmpile() 可以通过接受可选的属性,常用来实现不同的特殊功能和语法变更。

     例1:
     >>> import re     >>> s = r"^010-?\d{8}$" # 定义电话号码的正则     >>> re.findall(s,"010-63074291")     ['010-63074291']     >>> P_tel = re.compile(s)     >>> P_tel     <_sre.SRE_Pattern object at 0x0000000004130290>     >>> P_tel.findall("010-63074291") # 经过compile转换的正则表达式对象也能用于普通的re函数     ['010-63074291']

     例2:
     >>> import re     >>> s = r"hello"     >>> greeting = re.compile(s,re.I) # re.I 属性让正则表达式忽略大小写!     >>> greeting.findall("HELLO")     ['HELLO']     >>> greeting.findall("hello")     ['hello']     >>> greeting.findall("Hello")     ['Hello']

(5)re.match(pattern, string, flags=0) ——> match object or None

         在字符串的开始位置匹配正则。如果无匹配,则返回 None 。

     例:
     >>> import re     >>> s = r"abc"     >>> S = re.compile(s)     >>> S.match("abcdef") # 在字符串 "abcdef" 开始位置匹配 "abc"     <_sre.SRE_Match object at 0x00000000041C1440>     >>> S.match("hhhhhabc")     >>> print(S.match("hhhhhabc"))     None

(6)re.search(pattern, string, flags=0) ——> match object or None

         在字符串中匹配正则。如果无匹配,则返回 None 。

     例5:
     >>> import re     >>> s = r"abc"     >>> S = re.compile(s)     >>> S.search("abcdef")     <_sre.SRE_Match object at 0x00000000041C1440>     >>> S.search("hhhhhabc")     <_sre.SRE_Match object at 0x00000000041C1440>

(7)MatchObject 方法

     ——group():  返回被正则匹配的字符串;
     ——start():  返回匹配开始的位置;
     ——end():    返回匹配结束的位置;
     ——span():   返回一个元组包含匹配(开始,结束)的位置。

(8)re.finditer(pattern,string,flags=0) ——> iterator

         列出字符串中模式的所有匹配项,并作为一个迭代器返回。

     例:
     >>> import re     >>> s = r"abc"     >>> S = re.compile(s)     >>> S.finditer("ancdabsabchqw")     <callable_iterator object at 0x038EAA10>     >>> it = S.finditer("ancdabsabchqw")     >>> for i in it:     print(i.group())     abc

(9)re.sub(pattern, repl, string, count=0, flags=0) ——> string

         将字符串中所有 pattern 的匹配项用 repl 替换。

     例:
     >>> import re     >>> s = r"c..t"     >>> re.sub(s,"python","cvt ccct caat cet")     'cvt python python cet'     >>>      >>> s = r"a.b"     >>> re.sub(s,"hello","adb aab")     'hello hello'

(10)re.subn(pattern, repl, string, count=0, flags=0) ——> 2-tuple containing new_string and number

        与sub()实现相同的替换作用,但是subn()返回一个元组,其中包含新字符串和替换次数。

    例:
    >>> import re    >>> s = r"c..t"    >>> re.sub(s,"python","cvt ccct caat cet")    'cvt python python cet'    >>> re.subn(s,"python","cvt ccct caat cet")    ('cvt python python cet', 2)


(11)re.split(pattern, string, maxsplit=0, flags=0) ——> list

         根据模式的匹配项来分割字符串。

     例:
     >>> import re     >>> s = "abc.cdf+ghi*jk"     >>> re.split(r"[\.\+\*]",s)     ['abc', 'cdf', 'ghi', 'jk']


----------------常用的re的属性----------------

(1)re.I   re.IGNORECASE

         让正则表达式忽略大小写。此特性和locale无关。

(2)re.L   re.LOCALE

         做本地化识别,让\w、\W、\b、\B、\s和\S依赖当前的locale。

(3)re.M   re.MULTILINE

         多行匹配,影响'^'和'$'的行为,指定了以后,'^'会增加匹配每行的开始(也就是换行符后的位置);'$'会增加匹配每行的结束(也就是换行符前的位置)。

(4)re.S   re.DOTALL

         影响'.'的行为,平时'.'匹配除换行符以外的所有字符,指定了本标志以后,也可以匹配换行符。

(5)re.U   re.UNICODE

         让\w、\W、\b、\B、\d、\D、\s和\S依赖Unicode库。

(6)re.X   re.VERBOSE

         运用这个标志,你可以写出可读性更好的正则表达式:除了在方括号内的和被反斜杠转义的以外的所有空白字符,都将被忽略,
         而且每行中,一个正常的井号后的所有字符也被忽略,这样就可以方便地在正则表达式内部写注释了。


----------------正则表达式分组----------------
     例1:
     >>> email = r"\w{3}@\w+(\.com|\.cn)"#对.com与.cn取或     >>> re.match(email, 'zzz@csvt.com')     <_sre.SRE_Match object at 0x0000000003E64378>     >>> re.match(email, 'zzz@csvt.cn')     <_sre.SRE_Match object at 0x0000000003E643F0>#返回为匹配     >>> re.match(email, 'zzz@csvt.org')#不匹配,返回NONE     >>>      >>> re.findall(email, 'zzz@csvt.com')     ['.com']#当有分组时,findall优先只返回分组中匹配的数据

     例2:
     >>>print s     hhsdf ojd hello src=dsft yes hdf     dasj src=123 yes jdos     src=123 yes     hello src=python yes jkdfh       >>>r1 = r"hello src=.+ yes"     >>>re.findall(r1, s)     ['hello src=csvt yes', 'hello src=python yes']#找到 hello ... yes这样的特殊字符串     >>>r1 = r"hello src=(.+) yes"     ['csvt', 'python'] #得到src=csvt中csvt的值


----------------利用正则表达式写计算器----------------

     import re     s=raw_input()     t=re.findall(r"(\d+\.?\d*)([\+\-\*\/])(\d+\.?\d*)(=)",s)[0]     l=[]     for i in t:         l.append(i)         l[0]=int(l[0])     l[2]=int(l[2])     s={'+':lambda x,y:x+y,'-':lambda x,y:x-y,'*':lambda x,y:x*y,'/':lambda x,y:x/y}     print s[l[1]](l[0],l[2])


----------------利用正则表达式写爬虫----------------
(1)例:
     import re     import urllib     def getHtml(url):         page=urllib.urlopen(url)         html=page.read()         return html     def getImg(html):         reg=r'src="(.*?\.jpg)"'         imgre=re.compile(reg)         imglist=re.findall(imgre,html)         x=0         for imgurl in imglist:             imgurl=imgurl.replace("//","http://")             urllib.urlretrieve(imgurl,'%d.jpg'%x)             x+=1     html=getHtml('http://www.80s.tw/')     getImg(html)

(2)网页编码的修改

     import sys     type = sys.getfilesystemencoding()     #utf-8为网页编码,可能为gbk等     print html.decode('utf-8').encode(type)


          编码声明:

          # -*- coding:mbcs -*-  

原创粉丝点击