字符串的替换(非正则表达式)
>>> 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 = 1V = 5X = 10L = 50C = 100D = 500M = 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 = C200 = CC300 = CCC400 = CD500 = D600 = DC700 = DCC800 = DCCC900 = CM
因此有四种匹配方式
CMCD0-3个CD + 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-1212800 555 1212800.555.1212(800) 555-12121-800-555-1212800-555-1212-1234800-555-1212x1234800-555-1212 ext. 1234work 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>