Python 正则表达式

最近研究Python爬虫,很多地方用到了正则表达式,但是没好好研究,每次都得现查文档。今天就专门看看Python正则表达式。本文参考了官方文档 re模块

模式

首先正则表达式的语法我就不说了,这玩意倒是不算难,用的时候现查就行了——*正则表达式*_百度百科

在很多编程语言中,由于有转义字符这么一种东西的存在,导致正则表达式需要使用两个斜杠来处理。如果编程语言支持原始字符串,那么就不需要两个斜杠了。在Python中,字符串前面添加字母r即可把字符串变成原始字符串。

下面是一个正则表达式最简单的使用例子。我们查找所有以字母F开头的单词,不论大小写。这个例子使用了正则表达式模块的re.findall函数,它会返回所有符合模式的列表。

import re

text = 'fuck shit it make she forest'

results = re.findall(r'\b[Ff]\w+', text)
print(results)

如果某一个模式需要经常使用,我们可以把它编译为模式对象。然后从模式对象上调用各种正则查询方法。这样做的优点是:由于模式已经编译了,所以后续的查询速度会更快。

pattern = re.compile(r'\b[Ff]\w+')
print(pattern.findall(text))

查询标志

大部分查询方法还可以接受一个查询标志参数。查询标志让正则表达式具有不同的行为。下面一一说明。

标志

作用

re.A、re.ASCII

以ASCII模式查询,默认是Unicode模式

re.DEBUG

显示编译表达式的调试信息

re.I、re.IGNORECASE

忽略字母的大小写

re.L、re.LOCALE

以区域敏感方式查询匹配

re.M、re.MULTILINE

开启多行模式,开启之后行边界符^$会匹配每行的开始和结束,而不是整个字符串的开始和结束

re.S、re.DOTALL

使用此标志,会让点符号匹配所有字符,默认情况下点符号会匹配换行符以外的符号

re.X、re.VERBOSE

开启啰嗦模式,可以在写正则表达式的时候添加注释

下面是啰嗦模式的例子,来自Python官方文档。

a = re.compile(r"""\d +  # the integral part
                   \.    # the decimal point
                   \d *  # some fractional digits""", re.X)
b = re.compile(r"\d+\.\d*")

查询方法

查询方法有两种形式,第一种是re模块的函数,这些函数需要接受一个模式字符串。第二种就是从编译好的模式对象上调用,这样不需要模式字符串了。基本上大部分方法都有这两种形式,所以这里只需要介绍一种形式。

  • re.search(pattern, string, flags=0)方法查询字符串,返回第一个结果的匹配对象。不管有多少个满足条件的字符串,这个方法之返回第一个。如果查询不到,就返回None。
  • re.match(pattern, string, flags=0)查询字符串,当字符串的前面一部分和模式匹配的时候,会返回相应的匹配对象。如果不匹配,那么返回None。需要注意即使开启了多行模式,这个方法也只查询字符串最前面的一部分,不会查询每行的前面。
  • re.fullmatch(pattern, string, flags=0),如果整个字符串和模式匹配,返回相应的匹配对象。否则返回None。
  • re.split(pattern, string, maxsplit=0, flags=0),按给定正则表达式分割字符串。
  • re.findall(pattern, string, flags=0),最常用的方法,返回一个列表,包含所有匹配模式的字符串。
  • re.finditer(pattern, string, flags=0),和findall方法类似,不过返回的是一个迭代器。
  • re.sub(pattern, repl, string, count=0, flags=0),将字符串中匹配模式的部分使用repl替换,返回替换后的字符串。
  • re.subn(pattern, repl, string, count=0, flags=0),和sub方法类似,不过返回元组(新字符串,替换的数量)
  • re.purge(),清除正则表达式缓存。

在已编译好的正则表达式对象上还有以下几个属性。

  • flags,正则表达式的所有标志,包括flags参数设置的,compile方法编译传入的,以及正则表达式中本身的标志。
  • groups,正则表达式中捕获组的数量。
  • pattern,返回模式字符串。
  • groupindex,返回(?P<id>)形式的命名组和组编号键值对组成的字典。

匹配对象

上面提到的很多方法都返回匹配对象。匹配对象包含了一些方法和属性,方便我们进行查询。

最常用的就是group函数,它会返回指定组对应的字符串。下面的例子就查询了给定数据中的数据量和每页的条数。第0组返回整个匹配,第1组返回第一个匹配,以此类推……也可以采用命名组的方式。

text = '总共20条数据 每页5条'
pattern = re.compile(r'总共(?P<total>\d+)条数据\s+每页(?P<per>\d+)条')

match = pattern.match(text)
print(match.group(0))

另一个比较常用的函数就是groups(default=None),它返回所有组组成的元组。如果有的组没有匹配到字符串,就会显示为None,这时候可以使用default参数指定默认值。

text = '总共20条数据 每页5条'
pattern = re.compile(r'总共(?P<total>\d+)条数据\s+每页(?P<per>\d+)条')

match = pattern.match(text)

print(match.groups())

# 结果
# ('20', '5')

groupdict(default=None)返回组名和字符串组成的字典。还是上面的例子。

print(match.groupdict())
# {'total': '20', 'per': '5'}

startend函数返回给定组的在字符串的起始和结束索引,如果对应的组没有任何匹配,则返回-1。下面的例子来自Python官方文档,从电子邮件地址中去除remove_this。

>>> email = "tony@tiremove_thisger.net"
>>> m = re.search("remove_this", email)
>>> email[:m.start()] + email[m.end():]
'tony@tiger.net'

match.span([group])返回给定组的起始索引和结束索引组成的元组。

以上就是Python正则表达式的大部分内容了,灵活使用这些知识,可以获得强大的功能。关于如何巧用,就看大家的智慧了。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏用户2442861的专栏

深入 char * ,char ** ,char a[ ] ,char *a[] 内核

http://blog.csdn.net/daiyutage/article/details/8604720

20020
来自专栏尚国

PHP反序列化漏洞

这里你可以看到, 我代码里的类定义为: class F, 这个序列化就是 F, 我定义变量名字是filename, 它这里也是 filename, 我们可以修改...

12320
来自专栏Petrichor的专栏

python: 多属性排序

11920
来自专栏风中追风

JVM 的运行数据区

 栈空间里存放的是局部变量表,动态链接,操作数栈,以及是方法的出口;每个栈帧都会随着方法的开始和结束相应的出栈和入 栈;

36990
来自专栏技术之路

实例化和具体化详解

primer Plus在解释具体化和实例化看的有点乱,分解出来备忘 在代码中包含函数模板本身并不会生成函数定义,它只是用于生成函数定义的方案 编译器使用模板为我...

21550
来自专栏Phoenix的Android之旅

动态代理-进阶高级开发必学技能

关于代理模式的话题有很多, 在开发中经常用到的应该是静态代理模式,能很好的去耦合。 动态代理是代理模式的另外一种实现。

9630
来自专栏Create Sun

python 3.x 爬虫基础---正则表达式(案例:爬取猫眼信息,写入txt,csv,下载图片)

  正则表达式是对字符串的一种逻辑公式,用事先定义好的一些特定字符、及这些特定字符的组合,组成一个“规则的字符串”,此字符串用来表示对字符串的一种“过滤”逻辑。...

58040
来自专栏思考的代码世界

Python基础学习05天

15450
来自专栏Golang语言社区

Golang语言--中间的循环

在Go语言中只有很少的几个控制结构,它没有while或者do-while循环。 但是它有for、switch、if。而且switch接受像for那样可选的初始化...

42770
来自专栏程序员互动联盟

【Java基础】Java语言中的流程控制

前言: 上一篇文章写了面向对象的基础知识,接下来就开始写真正的代码了。逻辑判断和控制流程是编码中最小的逻辑单元,是整体逻辑的基石,所以每一个写代码的对于这一块...

38850

扫码关注云+社区

领取腾讯云代金券