Python关于一道正则排序面试题的解析

有字符串 A = ‘a33aa2a3aa5aa6aaa3aaa7aaa8aaa4’
求出所有含有一个或者多个 ‘a’ 子串加数字子串的子字符串(如:‘a33’, 'aa2’等),并排序,排序要求:
(1)含 ‘a’ 少的子字符串放在前,含 ‘a’ 多的子字符串放在后面;
(2)含 ‘a’ 子串数相同的再比较子串后面的数字大小,按从大到小排序。

import re
A =  'a33aa2a3aa5aa6aaa3aaa7aaa8aaa4'

list1 = re.findall(r'a+\d+', A)
sorted(list1, key=lambda x:(x.count('a'), -int(x[x.count('a'):])))

输出结果:

['a33', 'a3', 'aa6', 'aa5', 'aa2', 'aaa8', 'aaa7', 'aaa4', 'aaa3']
本题特点
  • 这里采用 ‘a+\d+’ 贪婪模式,而不是 ‘a+\d+?’ 非贪婪模式;否则只能匹配出 a3 ,不能匹配 a33
list1 = re.findall(r'a+\d+', A)
list2 = re.findall(r'a+\d+?', A)
print(list1)
print(list2)

['a33', 'aa2', 'a3', 'aa5', 'aa6', 'aaa3', 'aaa7', 'aaa8', 'aaa4']
['a3', 'aa2', 'a3', 'aa5', 'aa6', 'aaa3', 'aaa7', 'aaa8', 'aaa4']
  • sorted() 中key的排序规则可以有多个,比如:
    1)x.count(‘a’) 以字母 a 的个数大小排序;
    2)-int(x[x.count(‘a’):]) 以字母 a 后面数字的大小排序,加负号则按逆序排列;
    3)默认从小到大排序;
  • 注意 sorted() 中还有个参数 reverse = False/True:
    1)reverse = False,正序输出;
    2)reverse = True, 逆序输出;
其他解法

以每个元素中 ‘a’ 字母个数为 key ,以 ‘a’ 字母个数相同的元素构成的列表为value,生成字典;
比如:{1: [‘a33’, ‘a3’], 2: [‘aa2’, ‘aa5’, ‘aa6’], 3: [‘aaa3’, ‘aaa7’, ‘aaa8’, ‘aaa4’]}
然后遍历得到的字典,对字典的 value 列表排序后合并到结果列表中

import re
def sort_re(s):
    d = {}
    res = []
    list1 = re.findall(r'a+\d+', A)
    for k in list1:
        if k.count('a') not in d.keys():
            d[k.count('a')] = [k]
        else:
            d[k.count('a')].append(k)
    for k,v in d.items():
        res.extend(sorted(v, reverse=True))
    return res

if __name__ == '__main__':
    A =  'a33aa2a3aa5aa6aaa3aaa7aaa8aaa4'
    print(sort_re(A))

输出结果:

['a33', 'a3', 'aa6', 'aa5', 'aa2', 'aaa8', 'aaa7', 'aaa4', 'aaa3']
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值