Python Challenge 第10关(正则表达式)

本文通过解决一个特定的数字序列问题,探讨了正则表达式在Python中的应用,包括finditer、group等函数的使用方法及正则表达式语法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这一关乍一看很像行测题

给了一个未完成的序列,让推断第31个数的长度,瞪了好久怎么也没发现给出的这5个数字有什么关系。。。百度。。。原来每个数都是对前一个数的描述。如1,11,21,1211,那1211的意思就是前一个数有1个2,1个1。规律找到程序就不难写了。

然后一个丑陋的程序就诞生了:

elem='1'
for index in range(1,31):
    newelem=''
    pos=0
    while pos<len(elem):
        beg=elem[pos]
        count=0
        while pos<len(elem) and elem[pos]==beg:
            pos+=1
            count+=1
        newelem+=str(count)+beg
    elem=newelem
print len(elem)

逻辑之复杂,一点也不pythonic。


看看答案。。。原来这是一个正则表达式的问题。可以简单的描述为寻找包含连续的相同的数字序列的问题。如1113334555,找到其中的111,333,4,555。

答案如下:

import re
def describe(s):
    return "".join([str(len(m.group(0))) + m.group(1) for m in re.finditer(r"(\d)\1*", s)])
s = "1"
for dummy in range(30):
    s = describe(s)
print len(s)  # prints 5808


上述代码中不熟悉的有3块:

1、group的用法

2、finditer函数

3、正则表达式的写法:r"(\d)\1*"


OK,一点一点的来。先看group。

在正则表达式中引入分组的目的是为了匹配多个字符的重复情况,比如匹配abcabcabc这样的。python里关于group有以下几个函数:

group()==group(0):这两个函数都是为了获取整个成功匹配的字符串,跟括号没关系。

group(index):返回匹配第index个group的字符串。这句话乍一看没问题,仔细琢磨就觉得有歧义了。首先index是从1开始的,那么:

m=re.search(r"(\d\d)+","12345678")
print m.group()
print m.groups()
print m.group(1)
输出是什么呢?

第一条语句输出“12345678”,还是说跟括号无关,第二条语句输出("78",),不用说第三条语句就是输出“78”了。

(\d\d)并没有12345678分成四组,而是只匹配了最后的78,也就是说在这次匹配中因为只有一对小括号,所以只有一个group,而这个个group还是记录最后一次匹配成功的结果。

groups():输出的就是一个元组,即(group(1),group(2),...)。findall函数得到的groups的序列,比如:

>>> rst=re.search('(\d\w)(\w\d)','1dd21fg2')
>>> rst.group()
'1dd2'
>>> rst.groups()
('1d', 'd2')
>>> re.findall('(\d\w)(\w\d)','1dd21fg2')
[('1d', 'd2'), ('1f', 'g2')]

finditer函数和findall有点类似,只不过findall输出的是匹配成功的字符串(或元组)的list,而finditer输出的匹配成功的对象的迭代器。相对于search得到一个结果,findall和finditer得到所有的匹配结果。


最后一个是“奇怪”的正则表达式的写法,这个\1的意思是前面所出现的第一个group,自然(\d)\1*就表示重复出现的数字,另外,不要忘了最前面的小r。




                
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值