在Python编程中,字符串的处理是一个非常让人头疼的事情,但这是我们必须面对的。好消息是,它为我们提供了一个re模块来处理烦人的字符串;坏消息是,你必须掌握复杂的正则表达式。本节就来讲讲如何使用正则表达式来处理字符串。
P 1、什么是正则表达式
在Python官方知道手册中,称它是嵌入 Python 内部并通过 re 模块提供的一种微小的、高度专业化的编程语言。为什么会这么讲?因为它是一种专门从杂乱的字符串里提取出想要的目标信息的一门语言,它有自己的匹配规则,可以方便的提取字符串中的信息。
P 2、正则表达式规则
元字符是一类特殊含义的字符,就像Python里的内置关键字,在正则表达式里,它就是有特殊用途的字符。但特别需要注意的是它在有些情况下会失去元字符作用。主要的元字符,见下表:
表1 元字符表
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | [0-9]*|[a-z]*:表示匹配连续数字或连续小写字母 |
| | (test)(TEST):表示按组匹配,两组同时满足 |
表2 特殊序列含义表
| |
| |
| 匹配任何非数字字符,等价于字符类 [^0-9] 。 |
| 匹配任何空白字符,等价于字符类 [ \t\n\r\f\v] 。 |
| 匹配任何非空白字符,等价于字符类 [^ \t\n\r\f\v] 。 |
| 匹配任何字母与数字字符,等价于字符类 [a-zA-Z0-9_] 。 |
| 匹配任何非字母与数字字符,等价于字符类 [^a-zA-Z0-9_] 。 |
上述的元字符和特殊序列表,都是官方文档提供的部分内容,起始还有很多其它的字符,可以查阅官方指导手册。
P 3、正则表达式使用
本节逐步演示从字符串中提取字符。首先,我们用compile()编译一个正则表达式,然后用该正则表达式的findall()方法查找目标字符串中符合的字符串。直接上个案例看看吧:
# 创建一个字符串s = "Hello,world. I'm Rose."# 创建最简单的正则表达式 rule = re.compile('l')# findall()方法用于查找所有匹配字符串,并返回列表 print(rule.findall(s))# 输出 ['l', 'l', 'l']
这个例子中,创建的正则表达式是'l',即匹配字符'l',并在字符串中找到了3个'l',这不是我们想要的。现在,我们需要把字符串分割为两句话。如下:
# '[A-Z].*'表示大写字母开头后跟任意字符的字符串 rule = re.compile('[A-Z].*')print(rule.findall(s))# 输出["Hello,world. I'm Rose."]
怎么回事,大写'I'开头为什么没有被分割出来,而是被一次性全部读取了?这是正则表达式的贪婪模式导致的,贪婪模式下+、*都会尽可能多的匹配字符,而我们需要的是尽可能少的字符满足条件。来做个修改。# 相比上一个表达式,在*号后加入了?[.],此时?号用于消除*的贪婪模式,[.]用于限定结尾字符。 rule = re.compile('[A-Z].*?[.]')print(rule.findall(s))# 输出 ['Hello,world.', "I'm Rose."]
通过修改,我们把开头是大写字母,并且以英文句号结尾之间的字符提取出来了,并且成功将其分成了两句话。有小伙伴可能不屑一顾,认为用split()同样可以实现该效果。但如果字符串是上亿个呢?用split()又如何处理?而re模块为了降低内存使用情况,给我们提供了finditer()方法来返回一个生成器结果,大大节省内存开销。本文提供了一个简单的使用案例,小伙伴一定要实操正则表达式,否则你会陷入无尽的困惑。-------------------------它是数字世界里的一把杀猪刀
却总能巧夺天工
它的世界是纯粹0、1组合
却总能创造无尽幻想
......
本公众号关注数据价值分析、编程学习,将不定期更新社会热点数据分析结果、编程技巧,分享数据分析工具、方法、学习等内容,欢迎有兴趣的小伙伴加入。