>>> 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})$'
松散的正则表达式 和 普通表达式的区别
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]
的意思是: “s
、 x
或 z
”,但只匹配其中之一。[^abc]
的意思是:“ 除了a
、 b
或 c
之外的任何字符”。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>