Swift51.com
麦子学院 头像
麦子学院  2016-10-08 22:35

python正则表达式re模块详解

回复:0  查看:3071  

python中,正则表达式模块--re也是很常用的,今天就和大家一起来聊聊这部分内容,希望对大家学习python语言有所帮助。

首先是字符串中字符的替换问题,如果使用原生的Python方法,一般就是采用 replace 方法,下面我们采用re.sub方法同它进行比较。

第一个案例:我们的目标是把ROAD替换成RD.

python正则表达式re模块详解


似乎replace方法工作的不错阿,完成了我给定的任务。如果是下面这个例子呢?

python正则表达式re模块详解

这里很明显已经出现了问题,因为这个字符串中含有BROAD,其中也有ROAD四个字符,但是我们的目标并没有要求替换它。这里它也被替换成了BRD. ,这已经足以说明replace方法的局限性。当然,如果我们设计得当,这个方法也能用。

python正则表达式re模块详解

使用切片,我们也能做到这一点,仅仅把最后面的四个字符替换。不过,这种算法也有局限性,如果我们要将STREET 替换为ST. ,我们是不是应该保留最后面的六个字符?这样,每次替换都要修改代码,并且很容易造成错误,对于调试来说很麻烦。

那么让我们来试一下re.sub方法。

python正则表达式re模块详解

注意第一个参数,‘ROAD$’,其中美元符代表了字符串的结尾,也就是说匹配结尾的ROAD字符。同样的 ,代表字符串的开头。我很快发现, 有时候ROAD不一定在字符串的结尾,比如: s = '100 BROAD ROAD APT.3',此时,上面的方法就不适用了,没关系,我们还有\\b

python正则表达式re模块详解

是不是很神奇?\\b在左侧意味着左侧是个空格,在右侧意味着右侧是个空格,因此两侧\\b就是说,ROAD是一个独立的单词。也就是把独立的ROAD换成RD.,这和我们的目标相同。

第二个案例:罗马数字的匹配

在罗马数字中,用七个字母组合来表示数字。

I = 1

V = 5

X = 10

L = 50

C = 100

D = 500

M = 1000

下面是几个通常的规则来构成罗马数字:

大部分时候用字符相叠加来表示数字。I1, II2, III3VI6(挨个看来,是“5 和 1”的组合),VII7VIII8

含有10的字符(IXCM)最多可以重复出现三个。为了表示4,必须用同一位数的下一个更大的数字5来减去一。不能用IIII来表示4,而应该是IV(意思是比51)。40写做XL(比5010),41写做XLI42写做XLII43写做XLIII44写做XLIV(比5010并且比51)。

有些时候表示方法恰恰相反。为了表示一个中间的数字,需要从一个最终的值来减。比如:9需要从10来减:8VIII,但9确是IX(比101),并不是VIIII字符不能重复4次)。90XC900CM

表示5的字符不能在一个数字中重复出现。10只能用X表示,不能用VV表示。100只能用C表示,而不是LL

罗马数字是从左到右来计算,因此字符的顺序非常重要。DC表示600,而CD完全是另一个数字400(比500100)。CI101IC不是一个罗马数字(因为你不能从1001,你只能写成XCIX,表示比10010,且比101)。

对于千位数的匹配:

python正则表达式re模块详解

我们设定匹配模式是三个M,其中‘?’代表了这个参数是可选的,即三个可选的M参数。

第一次匹配M时,从^(字符串开头)开始匹配,匹配到一个M,另外两个由于是可选的,因此跳过,然后匹配到$(字符串结尾),匹配完成,返回一个匹配对象。第二,第三次匹配军成功。第四次匹配时,由于最多只能匹配上三个M,而给了四个M,因此在匹配完三个M时寻找$时,寻找不到,因此匹配失败,返回None

值得注意的时,因为三个参数都是可选的,因此空字符串也能匹配上。

对于百位数的匹配:

100 = C

200 = CC

300 = CCC

400 = CD

500 = D

600 = DC

700 = DCC

800 = DCCC

900 = CM

因此有以下四种匹配模式:

CM

CD

可能有03个字符C0个表示千位为0)。

D紧跟在03个字符C的后面。

其中后两种可以合并为一种:

一个可选的D,后面跟着03个字符C

python正则表达式re模块详解

此时,匹配模式中即包含千位,也包含百位。 ‘|’就是逻辑运算中或的意思,当出现几种情况并行时使用,当其中一个条件满足时,就停止执行后面的条件。

同样可以发现,空字符也是可以被匹配上的。

同理,我们分析了十位和个位的法则,也可以匹配上。

正则表达式非常强大,但它也并不是解决每一个问题的正确答案。你需要更多的了解来判断哪些情况适合使用正则表达式。某些时候它可以解决你的问题,某些时候它可能带来更多的问题。

预留问题:

1.“115.28.66.99[port=8080]”,这个字符串表示IP地址为115.28.66.99的服务器的8080端口是打开的,请用程序解析此字符串,然后打印出“IP地址为***的服务器的***端口是打开的

2.“115.28.66.99[port=21,type=ftp]”,这个字符串表示IP地址为115.28.66.99的服务器的21端口提供的是ftp服务,其中如果“,type=ftp”部分被省略,则默认为http服务。请用程序解析此字符串,然后打印出“IP地址为***的服务器的***端口提供的服务为***”

 

文章来源:博客园