python 正则表达式

字符串的替换(非正则表达式)

>>> s = '100 NORTH MAIN ROAD'
>>> s.replace('ROAD', 'RD.') 
'100 NORTH MAIN RD.'

>>> s = '100 NORTH BROAD ROAD'
>>> s.replace('ROAD', 'RD.')  
'100 NORTH BRD. RD.'            #replace()会替换全部ROAD 为 RD.

#如果想只替换最后一个ROAD 
>>> s[:-4] + s[-4:].replace(s)
'100 NORTH BROAD RD.'

正则表达式方式

>>> s = '100 NORTH BROAD ROAD'
>>> import re
>>> re.sub('ROAD$', 'RD.', s)     # ROAD$ 中 $标明字符串的结尾 即最后一个单词
'100 NORTH BROAD RD.'       
>>> re.sub('ROAD$', 'RD.', s)
'100 NORTH BROAD RD.' 

>>> s = '100 BROAD'
>>> re.sub('ROAD$', 'RD.', s)
'100 BRD.' 
>>> re.sub('\\bROAD','RD',s)       
#‘\b’意思是“在右边必须有一个分隔符”   为了使起作用 必须加一转义符'\'
'100 BROAD'
>>> re.sub(r'\bROAD$', 'RD.', s)   
#也可以这样  前面添加一个字符‘r’。它告诉python,字符串中没有任何字符需要转义

#但 如果要替换的字符不在最后 如
>>> s = '100 BROAD ROAD APT. 3'
>>> re.sub(r'\bROAD\b','RD.',s)    #ROAD前后都加‘\b’表示前后都有一分隔符  即为一单独的单词
'100 BROAD RD. APT. 3'

 

正则表达式检测罗马数字是否合法

      在罗马数字中,有七个不同的数字可以以不同的方式结合起来表示其他数字。

  • I = 1
  • V = 5
  • X = 10
  • L = 50
  • C = 100
  • D = 500
  • M = 1000

  罗马数字表示规则(点击查看)

     

正则表达式的匹配

千位的匹配
>>> import re
>>> pattern = '^M?M?M?$'             
# '^' 表示从字符串头部开始  '$'表示一直到字符串结尾  即匹配整个字符串 ?表示M是可选的
>>> re.search(pattern, 'M')     
<_sre.SRE_Match object at 0106FB58>
>>> re.search(pattern, 'MM')    
<_sre.SRE_Match object at 0106C290>

re模块最基本的方法是search()函数。它使用正则表达式来匹配字符串(M)。如果成功匹配,search()返回一个匹配对象。如果没有匹配到,search()返回None。

检查百位数

百位有不同的表达方式。

  • 100 = C
  • 200 = CC
  • 300 = CCC
  • 400 = CD
  • 500 = D
  • 600 = DC
  • 700 = DCC
  • 800 = DCCC
  • 900 = CM

因此有四种匹配方式

  • CM
  • CD
  • 0-3个C
  • D + 0-3 C
>>> import re
>>> pattern = '^M?M?M?(CM|CD|D?C?C?C?)$'  
>>> re.search(pattern, 'MCM')             
<_sre.SRE_Match object at 01070390>
>>> re.search(pattern, 'MD')              
<_sre.SRE_Match object at 01073A50>

>>> re.search(pattern, 'MCMC')    
#匹配失败 第一个M匹配成功 第二第三个匹配失败 然后匹配CM 成功  之后结束 还剩一个C 无法匹配 


使用语法{n,m}简化表达式

pattern = '^M?M?M?$' ==== pattern = '^M{0,3}$' 意思是“匹配字符串开始,然后是任意的0到3个M字符,再是字符串结尾”。
0 3 可以是任意数字 0表示最低匹配次数 3表示最多匹配次数
检查十位和个位
pattern = '^M?M?M?(CM|CD|D?C?C?C?)(XC|XL|L?X?X?X?)$' #十位匹配
pattern = '^M?M?M?(CM|CD|D?C?C?C?)(XC|XL|L?X?X?X?)(IX|IV|V?I?I?I?)$' #个位匹配

    使用{n,m}的语法来替代上面的写法会是什么样子呢?下面的例子展示了这种新的语法。

  pattern = '^M{0,3}(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})$'

松散正则表达式

松散的正则表达式 和 普通表达式的区别

  • 空白符被忽略。空格、制表符和回车在正则表达式中并不会匹配空格、制表符、回车。如果你想在正则表达式中匹配他们,可以在前面加一个\来转义。
  • 注释信息被忽略。松散正字表达式中的注释和python代码中的一样,都是以#开头直到行尾。它可以在多行正则表达式中增加注释信息,这就避免了在python代码中的多行注释。他们的工作方式是一样的。

        pattern = '^M{0,3}(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})$'   用松散表达式表示为

pattern = '''
^                   # beginning of string
M{0,3}              # thousands - 0 to 3 Ms
(CM|CD|D?C{0,3})    # hundreds - 900 (CM), 400 (CD), 0-300 (0 to 3 Cs),
                    #            or 500-800 (D, followed by 0 to 3 Cs)
(XC|XL|L?X{0,3})    # tens - 90 (XC), 40 (XL), 0-30 (0 to 3 Xs),
                    #        or 50-80 (L, followed by 0 to 3 Xs)
(IX|IV|V?I{0,3})    # ones - 9 (IX), 4 (IV), 0-3 (0 to 3 Is),
                    #        or 5-8 (V, followed by 0 to 3 Is)
$                   # end of string
'''

如果要使用松散正则表达式,需要传递一个叫re.VERBOSE的参数     

检测时 用 re.search(pattern, 'M', re.VERBOSE)

简单案例----电话号码匹配

下面是可能的电话号码格式:

  • 800-555-1212
  • 800 555 1212
  • 800.555.1212
  • (800) 555-1212
  • 1-800-555-1212
  • 800-555-1212-1234
  • 800-555-1212x1234
  • 800-555-1212 ext. 1234
  • work 1-(800) 555.1212 #1234

区域码是800,交换码是555,以及最后的后四码是1212。如果还有分机号,那就是1234

>>>phonePattern = re.compile(r'^(\d{3})-(\d{3})-(\d{4})$') #r表示 字符串中没有字符需要转义 \d表示任意的数字 \d{3} 则表示任意三个数字 中间用-隔开>>>phonePattern.search('800-555-1212').groups()('800', '555', '1212')

匹配成功 search()函数的返回值调用groups()方法。它会返回一个这个正则表达式中定义的所有分组结果组成的元组。
但是只能匹配 类似'800-555-1212' 没有分机号 用-隔开的号码

>>>phonePattern = re.compile(r'^(\d{3})\D+(\d{3})\D+(\d{4})\D+(\d+)$') #\D+ 表示至少一个不是数字的任意字符 \d+表示至少一个任意数字 可以匹配#这个表达式可以匹配 有分号 并且号码间有字符隔开的号码>>>phonePattern.search('800 555 1212 1234').groups()('800', '555', '1212', '1234')>>>phonePattern.search('800-555-1212-1234').groups()('800', '555', '1212', '1234')

>>>phonePattern = re.compile(r'^(\d{3})\D*(\d{3})\D*(\d{4})\D*(\d*)$')

#正则表达式处理电话号码没有分隔符的情况 
#\D* 表示不是数字的任意位数的任意字符 \d*表示任意位数的数字

>>>phonePattern.search('800-555-1212').groups()

('800', '555', '1212', '')

>>>phonePattern.search('work 1-(800) 555.1212 #1234') #但是头部有其它非数字字符的号码无法匹配

>>>

>>>phonePattern = re.compile(r'(\d{3})\D*(\d{3})\D*(\d{4})\D*(\d*)$') #去掉^ 跳过无关字符 从数字开始匹配>>> phonePattern.search('work 1-(800) 555.1212 #1234').groups()('800', '555', '1212', '1234')>>> phonePattern.search('800-555-1212')('800', '555', '1212', '')>>> phonePattern.search('80055512121234')('800', '555', '1212', '1234')

 

把它改写成松散正则表达式

>>> phonePattern = re.compile(r'''
                # don't match beginning of string, number can start anywhere
    (\d{3})     # area code is 3 digits (e.g. '800')
    \D*         # optional separator is any number of non-digits
    (\d{3})     # trunk is 3 digits (e.g. '555')
    \D*         # optional separator
    (\d{4})     # rest of number is 4 digits (e.g. '1212')
    \D*         # optional separator
    (\d*)       # extension is optional and can be any number of digits
    $           # end of string
    ''', re.VERBOSE)
>>> phonePattern.search('work 1-(800) 555.1212 #1234').groups()  
('800', '555', '1212', '1234')
>>> phonePattern.search('800-555-1212')                          
('800', '555', '1212', '')

正则表达式一些小的技巧:

  • ^ 匹配字符串开始位置。
  • $ 匹配字符串结束位置。
  • \b 匹配一个单词边界。
  • \d 匹配一个数字。
  • \D 匹配一个任意的非数字字符。
  • x? 匹配可选的x字符。换句话说,就是0个或者1个x字符。
  • x* 匹配0个或更多的x。
  • x+ 匹配1个或者更多x。
  • x{n,m} 匹配n到m个x,至少n个,不能超过m个。
  • (a|b|c) 匹配单独的任意一个a或者b或者c。
  • (x) 这是一个组,它会记忆它匹配到的字符串。你可以用re.search返回的匹配对象的groups()函数来获取到匹配的值。
  • [sxz] 的意思是: “sxz”,但只匹配其中之一。
  • [^abc] 的意思是:“ 除了abc 之外的任何字符”。

pa = r'\*(.+)\*'

re.sub(pa,r'<em>\l</em>',s)

此时 正则表达式会匹配尽可能多的 * *之间所有的字符  例如*dddd* 将变为<em>dddd</em>  *dd**ss*将变为<em>dd**ss</em>

pa = r'\*(.+?)\*'

此时 正则表达式会匹配尽可能少的 * *之间所有的字符   例如*dddd* 将变为<em>dddd</em>  *dd**ss*将变为<em>dd</em><em>ss</em>

posted @ 2012-02-23 19:33  cacique  阅读(2073)  评论(0编辑  收藏  举报
Copyright ©2011 Goodspeed Cheng