「Python」记一次凭想象重复造轮子的错误示范

  1. 读文档的意义在于知道别人已经实现了什么,怎么用
  2. 读源码的意义在于知道轮子是怎么造出来的
  3. 要好好学英语

用了三天的时间造了一个方形轮子,记录下来以吸取教训。
需求是用正则匹配一段文章,有n个匹配项,指定删除其中的某一个(第1个/第2个/倒数第1个…)
Python re库的文档是英文的,在提不起兴趣一句一句翻译下,从这里开始走上了一条岔路。
错误的实现思路:

import re
str1 = 'a1b1c1d1e.a2b2c2d2e.a3b3c3d3e.a4b4c4d4e.a5b5c5d5e.'
rules = {
    'a\d{1}': 2,
    'b\d{1}': -1,
    'c\d{1}': -3,
    'd\d{1}': -3,
}
for (reg, index) in rules.items():
    if index < 0:  # 反向匹配
        front = str1
        rear = ''
        for i in range(abs(index)):
            try:
                _front_ = re \
                    .search(r'.*(?=' + reg + ')', front) \
                    .group()
                _cur_ = re \
                    .search(r'' + reg + '$', re.search(r'.*(' + reg + ')', front).group()) \
                    .group()
                _rear_ = re.compile(r'.*(' + reg + ')').sub('', front)
            except AttributeError:
                break
            else:
                if i != (-1 - index):
                    rear = _cur_ + _rear_ + rear
                else:
                    rear = _rear_ + rear
                front = _front_
    else:  # 正向匹配
        front = ''
        rear = str1
        for i in range(index + 1):
            try:
                obj = re.search(r'' + reg, rear)
                start = obj.start()
                end = obj.end()
                _front_ = rear[0:start]
                _rear_ = rear[end:]
                _cur_ = rear[start:end]
            except AttributeError:
                break
            else:
                if i != index:
                    front = front + _front_ + _cur_
                else:
                    front = front + _front_
                rear = _rear_
    str1 = front + rear
print(str1)

正确的实现思路:
re.finditer()返回的对象中包含了匹配项的开始/结束位置,只要把前后内容拼起来,丢弃匹配的位置就可以了。

import re
str1 = 'a1b1c1d1e.a2b2c2d2e.a3b3c3d3e.a4b4c4d4e.a5b5c5d5e.'
rules = {
    'a\d{1}': 2,
    'b\d{1}': -1,
    'c\d{1}': -3,
    'd\d{1}': -3,
}
for (reg, index) in rules.items():
    pos = [(m.start(0), m.end(0)) for m in re.finditer(reg, str1)][index]
    print(pos)
    front = str1[:pos[0]]
    rear = str1[pos[1]:]
    str1 = front + rear
print(str1)

轮子跑起来后运行情况很糟糕,65000条数据清洗4条正则匹配项花了10分钟,更换完轮子方法后只用了2分钟。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值