为什么要使用正则表达式(Python版)

正则表达式(Regular Expression,常简写为regex、regexp或re),是文本处理中的一个重要概念。正则表达式通常被用来检索、替换那些符合某个模式(规则)的文本,简单地说,正则表达式就是一门专门用于字符串处理的增强语法。为了了解什么是正则表达式,我们先看一个简单的示例。

问题:在字符串 “我叫张三今年28岁,身高182cm,体重90kg,以前的手机号是13912345678,现在的手机号是:18812345678, 家里的电话是66658933,身份证号是 340403198501011234” 中找出所有的数字序列,如 28,182,90等。

如果我们直接选择编写程序来完成,自然是可以实现的,以下的代码即可完成。

def findnumbers(s):
    p = 0
    res = []
    for i in range(0, len(content)):
        if (p == 0 or not s[i-1].isdigit()) and s[i].isdigit():
            p = i
        elif s[i].isdigit() and (i + 1 == len(content) or not s[i+1].isdigit()):
            res.append(s[p:i+1])
    return res

以这段代码中,我们编写了一个findnumber(s) 函数,通过这个函数,我们对输入的字符串s的每个字符进行分析,分别找到以数据开头字符和结尾字符的位置,那么就可以将所有的数字提取出来。程序执行以后,我们可以得到以下的输出:

findnumbers: ['28', '182', '90', '13912345678', '18812345678', '66658933', '340403198501011234']

可见,所有的数字组合都按顺序找到了,达到了预期的目的。虽然任务完成了,但是我们发现有以下两个问题:首先,这个操作是复杂的,对于算法的实现和边界的判断有一定的复杂性,对很多同学来说在代码的编写上需要花费很多时间,包括编写、调试和修改;其次,这个算法兼容性太差,仅能满足这个简单的需求,如果我们提出新的要求,比如说对这些数字再进行筛选或分组,那么我们又要修改代码,才能满足新的要求。

那么有没有一种方式不需要修改代码,只需要指定我要查找的数据格式,就能把指定的内容返回呢?答案是肯定的,相信读者一定想到了就是正则表达式。那么就针对找数字这一相同问题,我们来看一下正则表达式如何实现,代码如下所示:

import re

content='我叫张三今年28岁,身高182cm,体重90kg,以前的手机号是13912345678,现在的手机号是:18812345678, 家里的电话是66658933,身份证号是 340403198501011234'
regex=re.compile('[0-9]+')
res = regex.findall(content)
print('all numbers:', res) 

程序运行以后,可以得到相同的查询结果:

all numbers: ['28', '182', '90', '13912345678', '18812345678', '66658933', '340403198501011234'] 

由于代码量只有寥寥几行,所以在没有任何说明之前,相信读者可以看懂大致内容,即首先我们引入了正则表达式的命名空间 re,然后定义了一个正则表达式的对象 regex,其中 regex=re.compile(’[0-9]+’) 是其筛选规则,而 regex.findall(content),则是执行过程,即在字符串查找相应的数字串。代码中唯一难以理解的就是 [0-9]+,它指定了所要查询的格式为连续长度的数字,其中[0-9]表示每个字符的内容只能是0-9之间的数字,而+表示其连续的长度为不小于1。所以, [0-9]+就是表示长度不小于1的连续数字的字符串。

通过这个示例,我们可以看到,利用正则表达式,只需要指定数据的格式,即可使用程序的re模块定义查询对象后,再通过执行查询操作找到我们所需要的内容。通过正则表达式,我们可以进一步对字符串操作进行抽象,将原先先理解需求,然后写代码实现的过程,变为将需求转换为字符串的正则表达式,然后让re模块去执行的过程。这种转换不仅大大简化了复杂字符串操作,同时也极大的提高了代码的质量,毕竟大部分程序员写的代码肯定没有由官方提供的re模块质量高。

附:参考代码

import re

pattern= R"1(3[0-9]|5[0-35-9]|8[025-9]){1}[0-9]{8}"
pattern = R"[0-9]+"

content='我以前的手机号是:13912345678,现在的手机号是:18812345678, 家里的电话是66658933,身份证号是 340403198501011234'
content0 = '18815694732'
regex=re.compile(R"1(3[0-9]|5[0-35-9]|8[025-9]){1}[0-9]{8}")
res = regex.findall(content)
print('regex.findall', res)


res = re.search(pattern, content)

print(res)
print('findall', re.findall(pattern, content))


pattern = 'abc'
content="abcd  bcd  abc  cadbabcgfe"

print('findall', re.findall(pattern, content))



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值