您的位置:首页 > 编程语言 > Python开发

看看如何在python中使用正则表达式(-)

2013-08-10 21:23 465 查看
       正则表达式是搜索,替换和解析复杂字符模式的一种强大而标准的方法。如果你曾经在其他的语言(如perl)中使用过它,由于它们的语法非常相似,你仅仅阅读一下re模块的摘要,大致了解其中可用的函数和参数就可以了。

       字符串也有很多方法可以进行搜索,替换和匹配,但是他们仅仅限于处理最简单的情况。搜索方法查找单个和固定编码的子串,并且他们是大小写敏感的。对于一个字符串s,如果要进行大小写不敏感的搜索,必须调用s.lower()和s.upper()将s转换成全小写或者是全大写,然后确保搜索串有着相匹配的大小写。replace()和split()方法有着类似的限制。

       如果能够通过简单的字符串函数完成,我们应该使用他们。但是,如果你发现你使用了许多不同的字符串函数和if语句来处理一个特殊情况,或者你组合使用了split()和join()函数而导致用一种奇怪的甚至是读不下去的方式理解列表,此时,你也许需要使用正则表达式了。

       尽管正则表达式语法较之普通的代码相对麻烦一些,但是却可以得到更可读的结果,与用一长串字符串函数解决方案相比要好的多。在正则表达式内部有多种嵌入方式注入注释,从而是之具有文档化的能力。

个案研究:街道地址

      
从一个老化系统中导出街道的地址,在将他们导入新的系统之前,进行清理和标准化。

Example1:在字符串的结尾匹配

>>> s = '100 NORTH MAN ROAD'
>>> s.replace('ROAD','RD.')
'100 NORTH MAN RD.'
>>> s = '100 NORTH BROAD ROAD'
>>> s.replace('ROAD','RD.')
'100 NORTH BRD. RD.'
>>> s[:-4] + s[-4:].replace('ROAD','RD.')
'100 NORTH BROAD RD.'
>>> import re
>>> re.sub('ROAD$','RD.',s)
'100 NORTH BROAD RD.'
        我们的目标是将街道进行地址标准规范化,‘ROAD’通常被略写为‘RD.’。乍看起来,我以为这个太简单,只用字符串的方法replace()就可以了,毕竟,所有的数据都进行的大写,因此大小写的匹配问题已经不是问题了,在一般的例子中就可以胜任了。不幸的是生活中充满了特例,如‘ROAD’这个次出现了两次,一次是作为街道的名字,一次是街道本身,replace就不能很好的解决这个问题,而且原始的数据也被破坏掉了,为了解决多次出现‘ROAD’的问题,我们可以去规定就是在街道的结尾的最后四个字符进行替换检查,但是,你已经感觉这个并不是变得特别方便了,现在是时候转换到正则表达式了。来看第一个参数'ROAD$'这个正则表达式还是很简单的,只有当‘ROAD’出现在一个字符串的末尾时才进行匹配,利用re.sub()进行字串的匹配,字符$表示在串的末尾,‘^’表示串的开头,继续向下看,很快我们发现,仅仅匹配地址末尾的'ROAD'不是很好,因为不是所有的地址都包括表示街道的单词‘ROAD’,有一些直接以街道名结尾,但是大部分情况下是不会遇到这样的情况,但是如果,街道的名称为‘BROAD’,那么正则表达式将会匹配出错。

Example2:匹配整个单词

>>> s = '100 BROAD'
>>> re.sub('ROAD$','RD.',s)
'100 BRD.'
>>> re.sub('\\bROAD$','RD.',s)
'100 BROAD'
>>> re.sub(r'\bROAD$','RD.',s)
'100 BROAD'
>>> s = '100 BROAD ROAD APT.3'
>>> re.sub(r'\bROAD$','RD.',s)
'100 BROAD ROAD APT.3'
>>> re.sub(r'\bROAD\b','RD.',s)
'100 BROAD RD. APT.3'


          我真正想做的就是,当‘ROAD’出现在字符串的末尾时,并且作为一个独立的单词时,而不是一些长单词的一部分,才对他进行匹配,为了在正则表达式中表达这个意思,我们利用\b,他的含义就是‘单词的边界必须在这里’,在python中,由于字符‘\’在一个字符串中必须转义,会变的非常麻烦,有时候,这类问题被成为‘反斜线的灾难’这也是在perl中正则表达式比python表达式相对容易的原因之一,为了避免反斜线灾难,你可以利用所谓的原始字符串,只要为字符添加一个前缀r就可以,这将告诉python,字符串中的所有字符都不转义,因此我推荐只要处理正则表达式,就使用原始字符串,否则事情会变的很混乱。但是很不幸的是,我很快发现更多与我的逻辑想矛盾的地方,如果,街道的地址包含有作为整个单词的ROAD,但是并不是在末尾,因为地址在街道的后面可能还会有一个房间号,由于ROAD不在字符串的末尾,因此就没有匹配上,为了解决这个问题,我们去掉了$字符,加上一个\b,现在,正则表达式:匹配字符串中作为整个单词出现的ROAD了,无论是在末尾还是在中间。

参考自:diveintopython-zhcn
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息