python | 探寻python正则表达式-1

简介: python | 探寻python正则表达式-1

image.png

面试官: 现在有一个需求,我们需要分析一个文本中的所有数据,需要抓出其中的所有人的电话号码,以 xxx-xxxx-xxxx 或者是 xxx-xxxxxxxx 或者是 xxxxxxxxxxx 为格式,请用python来编写一个程序来实现。


我: 使用re模块,额。。。。。,我知道,又没了。

这边文章,我们将介绍python正则表达式工具re,当然了,还是要说明一下python使用环境为: Python 3.6.8

image.png

什么是正则表达式


正则表达式定义


正则表达式(regex) 是描述文本模式的一种表达式,由模式字符串特殊字符组成,用于匹配、搜索、替换等等。



阐述模式和特殊字符


好了,正则表达式就介绍完了,咋的?还不明白啊。其实我刚开始看到时候,也不明白,我们举个小栗子来介绍一下模式和特殊字符吧。


假设有一个正则表达式是 abcdef,那么它的模式字符串就是abcdef,特殊字符没有。


假设还有一个正则表达式是^juejin.*pdudo$,在此正则表达式中:


  • ^ 是特殊字符,表示匹配字符串的开头。
  • juejin 是一个模式字符串,表示需要匹配的字面字符串。
  • .是一种特殊语法,. 表示匹配任意一个字符,* 表示重复前面的字符零次或多次。因此,".*" 表示匹配任意长度的字符串。
  • pdudo 是一个模式字符串,表示需要匹配的字面字符串。
  • $ 是特殊字符,表示匹配字符串的结尾。



python提供的特殊字符有哪些


额,这里又有一个问题了,你知道特殊字符有哪些么?


由于我们使用python来写正则,所以我们直接看python文档就可以了,例如:docs.python.org/zh-cn/3.7/l…


我们找到关于特殊字符的描述就可以了,例如:

image.png


这里就不原班搬运了。

python中,我们一般通过标准库re来编写正则表达式,接下来,我们一起来看看吧。



为什么要使用正则表达式


在介绍这个段落内容之前,我们不妨写个小功能,我们想要搜寻目录下文本的内容,内容必须包含pdudo


由于码上掘金不太好写文件之类的,所以我们给抽离出来定义为列表的形式。


大概内容如下:

image.png


使用暴力搜索法来搜索特定字符串

我们想搜索上述案例中,关于pdudo的字符串,先尝试一种不用正则表达式的方式。这个很简单,我们直接使用in关键字就可以完成,来看代码:


def main() -> None:
    testTxt = [
        ["今天,小狗pdduo迷路了。好心的主人找了很久也没找到它,心急如焚。终于,在一个角落里发现了它。小狗抬起头,看着主人,高兴地摇了摇尾巴,似乎在说:“谢谢你救了我。"],
        ["教室里传来一阵阵笑声,原来是pdudo调皮捣蛋。老师生气地走过去,pdudo马上低下了头。可当老师转过身时,pdudo又偷偷地对同桌saying:“快看,我藏起来了!"],
        ["爷爷退休后,经常给家里打电话聊天。他总是说:“最近有一个新朋友叫puddo,跟我聊得很开心。”后来才知道,那是他认识的一位年轻的志愿者,每周会给他打电话陪他聊天。"],
        ["在海滩上散步时,我们捡到了一个漂亮的贝壳,上面写着“pdduo”。这让我们想起了一个童话故事,于是我们决定将它带回家,留作纪念。"],
        ["昨天晚上,我在电视上看到了一个关于puddo的纪录片。它讲述了一只顽皮的小熊,经过几年的努力和奋斗,终于成为了丛林之王。这个故事让我想起了自己的梦想,也让我更加坚定要努力实现它。"]
    ]
    strs = "pdudo"
    for i in testTxt:
        if strs in i[0]:
            print(i)
if __name__ == '__main__':
    main()



还是很简单嘛,但是现在问题来了,如果要匹配以p开头以d结尾,匹配的字符串为5个字符,这个如果硬写,应该怎么写呢?


额,这个要写,也难不倒,对吧? 我们可以遍历一下。

逻辑为: 如果找到p字符,确定下标,再根据下标+4判断是否是字符d,如果是就输出,对吧?来写下:

strs = "pdudo"
for i in testTxt:
    j = 0
    while j < len(i[0]):
        if strs[0] == i[0][j] :
            if (j+4 < len(i[0])) and i[0][j+len(strs)-1] == strs[len(strs)-1]:
                print("search ok,pdudo中的p下标为: ",j,"原字符串为:",i[0])
                break
        j = j + 1

上述代码,就是用最原始的方法,遍历所有字符,如果找到了p则再判断该字符后4个字符位置是否是o,如果是则将p的下标和整段话都打印出来。

详细代码,可以看这里:


def main() -> None:
    testTxt = [
        ["今天,小狗pdduo迷路了。好心的主人找了很久也没找到它,心急如焚。终于,在一个角落里发现了它。小狗抬起头,看着主人,高兴地摇了摇尾巴,似乎在说:“谢谢你救了我。"],
        ["教室里传来一阵阵笑声,原来是pdudo调皮捣蛋。老师生气地走过去,pdudo马上低下了头。可当老师转过身时,pdudo又偷偷地对同桌saying:“快看,我藏起来了!"],
        ["爷爷退休后,经常给家里打电话聊天。他总是说:“最近有一个新朋友叫puddo,跟我聊得很开心。”后来才知道,那是他认识的一位年轻的志愿者,每周会给他打电话陪他聊天。"],
        ["在海滩上散步时,我们捡到了一个漂亮的贝壳,上面写着“pdduo”。这让我们想起了一个童话故事,于是我们决定将它带回家,留作纪念。"],
        ["昨天晚上,我在电视上看到了一个关于puddo的纪录片。它讲述了一只顽皮的小熊,经过几年的努力和奋斗,终于成为了丛林之王。这个故事让我想起了自己的梦想,也让我更加坚定要努力实现它。"]
    ]
    strs = "pdudo"
    for i in testTxt:
        j = 0
        while j < len(i[0]):
            if strs[0] == i[0][j] :
                if (j+4 < len(i[0])) and i[0][j+len(strs)-1] == strs[len(strs)-1]:
                    print("search ok,pdudo中的p下标为: ",j,"原字符串为:",i[0])
                    break
            j = j + 1
if __name__ == '__main__':
    main()


上面案例实现起来多很难吧,如果再上一层台阶,匹配字符串,必须是p在前和d灾后,中间的字符串必须由udo来组成,是不是更加头大了啊,这个时候,正则表达式就很好做这个事情。



使用正则表达式来匹配字符串

我们使用正则表达式,仅需定义一个匹配模式,而后无脑调用findall即可,例如查询可以这样写:


pattern = "p[duo]{3}o"
for i in testTxt:
    if re.findall(pattern, i[0]):
        print(i)

其中,p[duo]{3}o代表以p在前,以o在后,中间必须包含3个字符,字符局限于duo之间。

使用的时候,可以使用python标准库re,调用方法findall,参数为匹配模式 和 需要匹配的字符串即可。


可以看代码实现:

import re
def main() -> None:
    testTxt = [
        ["今天,小狗pdduo迷路了。好心的主人找了很久也没找到它,心急如焚。终于,在一个角落里发现了它。小狗抬起头,看着主人,高兴地摇了摇尾巴,似乎在说:“谢谢你救了我。"],
        ["教室里传来一阵阵笑声,原来是pdudo调皮捣蛋。老师生气地走过去,pdudo马上低下了头。可当老师转过身时,pdudo又偷偷地对同桌saying:“快看,我藏起来了!"],
        ["爷爷退休后,经常给家里打电话聊天。他总是说:“最近有一个新朋友叫puddo,跟我聊得很开心。”后来才知道,那是他认识的一位年轻的志愿者,每周会给他打电话陪他聊天。"],
        ["在海滩上散步时,我们捡到了一个漂亮的贝壳,上面写着“pdduo”。这让我们想起了一个童话故事,于是我们决定将它带回家,留作纪念。"],
        ["昨天晚上,我在电视上看到了一个关于puddo的纪录片。它讲述了一只顽皮的小熊,经过几年的努力和奋斗,终于成为了丛林之王。这个故事让我想起了自己的梦想,也让我更加坚定要努力实现它。"]
    ]
    pattern = "p[duo]{3}o"
    for i in testTxt:
        if re.findall(pattern, i[0]):
            print(i)
if __name__ == '__main__':
    main()

使用标准库re,很容易理解这个事情的。



正则表达式案例


还记得文章最开始的时候,我们需要写一个程序,以此来搜索以 xxx-xxxx-xxxx 或者是 xxx-xxxxxxxx 或者是 xxxxxxxxxxx 为格式的电话号码么? 我们了解了上述正则表达式后的写法后,应该会写了吧,我们来试试看:


我们构建了一份假的富婆通讯录,内容如下:

image.png

我们将其放置到列表中,我们想搜索一下这3种电话号码,分别为: xxx-xxxx-xxxx 、 xxx-xxxxxxxx 、 xxxxxxxxxxx ,就目前而言我们知晓手机号均为1开头,而后全是数字。所以如上三种方法,正则表达式可以这样写:

字符串 正则表达式
xxx-xxxx-xxxx 1[0-9]{2}-[0-9]{4}-[0-9]{4}
xxx-xxxxxxxx 1[0-9]{2}-[0-9]{8}
xxxxxxxxxxx 1[0-9]{10}

其中正则表达式的 [] 代表合集,即: [abc]可以匹配abc的其中一个,而后面的{n}则可以匹配前面[]中数字n次。


拿这个举例,模式 和 特殊字符,我们分别用 蓝色 和 红色 标注出来一下:


image.png

如果不明白的,我可以滑到最上面去看看。

但是我们需要匹配3个,我们如何用一个正则表达式来编写呢?答案是可以使用竖线分割|,于是乎,正则表达式就成了这样的了: 1[0-9]{2}-[0-9]{4}-[0-9]{4}|1[0-9]{2}-[0-9]{8}|1[0-9]{10}

最后使用re调用findall就可以了。


import re
def main() -> None:
    testTxt = [
        ["姓名: 张X 女 英文名: Emily 北京市海淀区中关村大街X号 138-1234-5678 爱好: 游泳 职业: 律师"],
        ["姓名: 李X英 性别: 女 英文名: Olivia 地址: 成都市高新区天府大道中段XXX号 电话号码: 156-12345678 健身 职业: 医生"],
        ["姓名: 赵X华 女 英文名: James 武汉市江汉区解放大道XX号 15812345678 摄影 职业: 教育工作者"]
    ]
    pattern = "1[0-9]{2}-[0-9]{4}-[0-9]{4}|1[0-9]{2}-[0-9]{8}|1[0-9]{10}"
    for i in testTxt:
        print(re.findall(pattern,i[0]))
if __name__ == '__main__':
    main()

如果我们我们还想将名字和职业以及电话号码串起来呢? 我们可以定义3个正则表达式,分别是电话、姓名以及职业:

telPattern = "1[0-9]{2}-[0-9]{4}-[0-9]{4}|1[0-9]{2}-[0-9]{8}|1[0-9]{10}"
namePattern = "姓名: .*? "
jobPattern = "职业: .*?$"

我们改改代码,就可以实现了:

image.png

关于更多的正则表达式,可以查看上述提供的文档,也可以看下一篇博客。



总结


该篇文章,先是介绍了正则表达式,而后解释了正则表达式中的模式和特殊字符,最后对比了一下使用正则表达式和不是用正则表达式的区别。最后的最后,提供了一个正则表达式搜索电话号码的案例。


特别是python文档上的特殊字符,应该好好了解下。

后面,python使用正则表达式,只能使用re.findall么? 我们后面会详细介绍python re


相关文章
|
2月前
|
Python
"揭秘!Python如何运用神秘的正则表达式,轻松穿梭于网页迷宫,一键抓取隐藏链接?"
【8月更文挑战第21天】Python凭借其强大的编程能力,在数据抓取和网页解析领域表现出高效与灵活。通过结合requests库进行网页请求及正则表达式进行复杂文本模式匹配,可轻松提取网页信息。本示例展示如何使用Python和正则表达式解析网页链接。首先确保已安装requests库,可通过`pip install requests`安装。接着,利用requests获取网页内容,并使用正则表达式提取所有`&lt;a&gt;`标签的`href`属性。
33 0
|
3天前
|
Python
Python 正则表达式高级应用指南
正则表达式是文本模式匹配的强大工具,Python 的 `re` 模块支持其操作。本文介绍正则表达式的高级应用,包括复杂模式匹配(如邮箱、电话号码)、分组与提取、替换操作、多行匹配以及贪婪与非贪婪模式的区别。通过示例代码展示了如何灵活运用这些技巧解决实际问题。
12 7
|
11天前
|
索引 Python
30天拿下Python之正则表达式
30天拿下Python之正则表达式
|
12天前
|
数据采集 Python
Python正则表达式提取车牌号
Python正则表达式提取车牌号
12 0
|
14天前
|
数据采集 Python
Python正则表达式提取车牌号
Python正则表达式提取车牌号
10 0
|
16天前
|
存储 数据处理 Python
Python中利用正则表达式进行文本处理
【9月更文挑战第24天】本文通过深入浅出的方式,介绍如何在Python中使用正则表达式进行文本处理。我们将从基础语法开始,逐步深入到复杂匹配模式的构建,最后通过实际案例展示正则表达式在文本分析中的高效应用。文章旨在帮助读者掌握正则表达式的使用技巧,提高数据处理效率。
|
2月前
|
安全 数据安全/隐私保护 Python
python中的正则表达式
python中的正则表达式
|
2月前
|
Python
告别死记硬背:掌握Python正则表达式re模块的高效应用&[面向百度编程]
Python中正则表达式的高效应用,通过内置的`re`模块,讲解了如何匹配、提取和替换字符串,并提供了相关示例代码,同时提倡通过实践来掌握正则表达式的使用,而不是仅仅依赖网络搜索。
38 1
|
2月前
|
Unix Shell Python
在Shell中转换Python正则表达式
结合以上提到的注意事项与差异点,就能在Shell环境中巧妙地转换并使用Python正则表达式了。务实和节省时间的做法是,将一些常见Python正则模式记在手边,随时查阅并对照POSIX标准进行调整。同时,借助在线正则表达式测试器和文档也能有效地提升在Shell环境中处理正则表达式的能力。
34 5
|
2月前
|
Python
Python中利用正则表达式进行文本处理的实用指南
【8月更文挑战第31天】在编程的世界里,文本处理是日常工作的一部分。就像厨师用刀切菜一样,我们用正则表达式来切割、匹配和修改字符串。这篇文章将教你如何像大厨一样使用Python中的正则表达式库,让你的文本处理技能更上一层楼。