作者:zhbzz2007 出处:http://www.cnblogs.com/zhbzz2007 欢迎转载,也请保留这段声明。谢谢!

1 模块简介

正则表达式是一门小语言,你可以在Python中或者其他编程语言中使用。你经常可以看到正则表达式可以写为“regex”,“regexp”或者就是“RE”。一些语言,例如Perl或者Ruby,语言本身直接支持正则表达式。Python通过一个库来支持正则表达式,因此你需要引入这个库。正则表达式的主要用途就是匹配字符串。你先通过正则表达式来创建字符串匹配规则,然后将其应用到字符串,观察是否存在匹配。

正则表达式作为一门小语言,你不可能使用它来满足所有的字符串匹配需求。另外,尽管有些任务你可以使用正则表达式来完成,但是它可能非常复杂,以至于很难去调试。这种情况下,你应该只使用Python。值得注意的是,Python在文本分析方面是一门优秀的语言,它可以完成你通过正则表达式所做的任何事情。但是,它或许需要写很多代码来完成,并且会比正则表达式的速度慢,因为正则表达式是在C语言下编译和执行的。

2 模块使用

2.1 匹配字符

当你想匹配字符串中的一个字符,大部分情况下,你可以仅仅使用那个字符或者子字符串。如果我们想匹配“dog”,我们就使用字母“dog”。当然,正则表达式保留了一些字符。这些就是元字符。下面就是Python中正则表达式所支持的元字符,

.^$*+?{}[]|()

下面我们将会花费一些时间来了解它们是如何工作的。你将会遇到的一个最常见的元字符对就是方括号:[和]。它们经常被用于创建字符类,就是你想匹配的一个字符集合。你或许单独列出每个字符,如[xyz]。这个就会匹配括号中任意一个字符。你也可以使用破折号来表示一个字符范围,例如[a-g]。在这个例子中,我们将会匹配从a到g中任意一个字符。

为了执行一个实际的搜索过程,我们需要增加一个起始字符来进行查找,另外还需要一个结束字符。为了让这个过程更容易,我们使用星号,它允许重复,而不是匹配 将会告诉正则表达式,先前的字符可以匹配0次或者多次。

一个简单的例子如下所示,

a[b-f]*f

这个正则表达式意味着,我们首先查找字符a,0个或者多个[b-f]中的字符,需要以字符f结束。让我们在Python中使用这段代码,

>>> import re
>>> text = "abcdfghijk"
>>> parser = re.search('a[b-f]*f',text)
>>> parser
<_sre.SRE_Match object at 0x106b30b90>
>>> parser.group()
'abcdf'

这段代码中,表达式会首先查找我们传入的字符串,在这里,字符串就是“abcdfghijk”。它将会发现开始位置的字母a会被匹配上。有一个末尾是星号的字符类,它将会读取剩余的字符串,观看是否匹配。如果不匹配,它就会回退一个字符来尝试找到一个匹配。

最神奇的地方就是我们调用re模块的search函数。如果我们没有找到一个匹配,就会返回None。否则,我们就获得一个Match对象,你可以在上述代码中看到。为了看到实际匹配上什么,你需要调用group方法。

还有另外一个类似于 * 的重复元字符。它就是 + ,将会匹配一次或者多次。这与 * 有所不同, * 只匹配0次或者多次。 + 需要查找的字符至少出现一次。

最后两个重复的元字符也有所不同。?,只匹配一次或者0次,意味着它前面的字符是可选的。一个简单的例子就是“co-op”,它就会匹配“coop”和“co-op”。

最后一个重复元字符就是{a,b},这里a和b都是十进制整数。这就意味着,它必须至少重复a次,最多重复b次。你可以按照如下方式来书写,

xb{1,4}z

这是一个很简单的例子,但是它将会匹配xbz,xbbz,xbbbz和xbbbbz,xz不会匹配上,因为它没有字符b。

下一个元字符就是^。这个字符允许我们匹配没有出现在字符类中罗列出的字符,它是字符类的补集。只有我们将^放在字符类里面,它才会生效。如果它在字符类的外面,我们将会匹配字符^。一个很好的例子就是:[^a]。这个将会匹配除字符a之外的任意字符。

字符^作为锚,另外一个作用是用于匹配字符串的起始位置,相对应的字符串结尾的锚就是$。

我们已经花费了相当多的时间来介绍很多正则表达式的概念。下面几节,我们将会深入几个实际的代码例子。

2.2 使用搜索进行模式匹配

让我们先学习一下基础的模式匹配。当你使用Python来查找一个字符串中的模式,你可以像上一节那样,使用search函数,代码如下:

import retext = "Teh ants go marching one by one"strings = ["the","one"]for strig in strings:match = re.search(string,text)if match:print('Found "{}" in "{}"'.format(string,text))text_pos = match.span()print(text[match.start(),match.end()])else:print('Did ot find "{}"'.format(string))

这个例子中,我们首先引入re模块,并创建一个简单的字符串。然后我们创建包含两个要在主字符串进行查找的字符串。下一步,我们在要查找的字符串上进行遍历,并进行搜索。如果匹配上,我们将其打印出来。否则,我们告诉用户,字符串没有找到。

还有其他的函数需要解释一下。你或许注意到我们调用了span函数,这个会告诉我们待匹配的字符串的起始位置和结束位置。如果你将我们赋值的范围给text_pos打印出来,你将会得到一个元组,类似于(21,24)。另外你还可以调用一些其它方法,就是我们接下来要做的。我们使用start和end来获取匹配的起始位置和结束位置,它们就是我们所获取范围的两个数字。

2.3 转义字符

还有一些你在Python中搜索时需要的转义字符,下面就是一个转义字符列表以及相应的解释。

d 匹配数字
D 匹配非数字
s 匹配空格
S 匹配非空格
w 匹配数字字母
W 匹配非数字字母
你可以在字符类中使用转义字符,例如[\d],这就允许我们查找任何一个数字,等价于[0-9]。我非常推荐你使用它们。

2.4 编译

re模块允许你编译频繁搜索的表达式。这就允许你将表达式转换为SRE_Pattern对象。你可以在搜索函数中使用这个对象。让我们使用之前的代码,并将其修改一下用于编译,

import retext = "The ants go marching one by one"strings = ['the','one']for string in strings:regex = re.compile(string)match = re.search(regex,text)if match:print('Found "{}" in "{}" '.format(string,text))text_pos = match.span()print(text[match.start():match.end()])else:print('Did not find "{}"'.format(string))

你将会注意到在这里,我们通过在列表中每个字符串调用编译来创建我们的模式对象,并将结果赋值给变量regex。我们将regex传递给搜索函数。剩余的代码都是相同的。主要的原因就是使用编译用于保存以便在后续代码中继续使用。当然,编译也可以使用标志位,这样可以使能不同特殊的功能。

当你编译模式时,他们将会自动获得缓存,你就不需要在代码中大量使用正则表达式,你不需要将已编译的对象保存到变量中。

2.5 编译标志位

Python 3中有7个编译标志位,可以用于改变编译模式行为。让我们看看这些标志位,并观察如何使用这些标志位。

2.5.1 re.A/re.ASCII

当遇到如下的编码:w、W、b、B、d、D、s和S,ASCII标志位告诉Python只匹配ASCII,而不是全部的Unicode。re.U/re.UNICODE标志位主要是为了后向兼容性,现在这些标志位已经废弃,因为Python 3默认匹配Unicode。

2.5.2 re.DEBUG

这个将会显示关于编译表达式的调试信息。

2.5.3 re.I/re.IGNORECASE

如果你想执行大小写不敏感匹配,那么这个标志位就可以起到这个作用。如果你的表达式是[a-z],如果你用这个标志位进行编译,你的模式也会匹配大写字符。这个也会对Unicode编码有效,并不会受到当前区域的影响。

2.5.4 re.L/re,LOCALE

w、W、b、B、d、D、s和S依赖当前区域。但是,Python官方文档说明你不应该依赖这个标志位,因为区域机制本身不可靠。取而代之,仅仅使用Unicode匹配。官方文档表示这个标志位仅仅对字节匹配有意义。

2.5.5 re.M/re.MULTILINE

当你使用这个标志位,你在告诉Python使得^模式字符匹配字符串的开始以及每行的开始。它也告诉Python使得$模式字符匹配字符串的末尾和每行的末尾,这个与默认的有些区别,具体可以查看官方文档。

2.5.6 re.S/re.DOTALL

这个标志位使得.元字符匹配任何字符。没有这个标志位,它将会匹配除了换行符之外的任何字符。

2.5.7 re.X/re.VERBOSE

如果你发现正则表达式很难阅读,这个标志位就会满足你的需要。它允许你将正则表达式中逻辑独立部分可视化出来,甚至添加注释。模式中的空格将会被忽略,除了在字符类中或者当空格在未绑定的反斜杠的前面。

2.5.8 使用编译标志位

让我们来看一个使用VERBOSE编译标志位的简单例子。一个例子就是邮箱地址查找正则表达式,例如,r'[w.-]+@[w.-]+',然后使用VERBOSE标志位来添加一些注视。代码如下所示,

re.compile('''[\w\.-]+    # the user name@[\w\.-]+    # the domain''',re.VERBOSE)

让我们来学习如何查找多个匹配。

2.6 查找多个实例

我们之前所看到是如何查找字符串中的第一个匹配。但是如果你有一个多个匹配的字符串,该如何处理?让我们先回顾一下如何查找一个单独的匹配:

import re
silly_string = "the cat in the hat"
pattern = "the"
match = re.search(pattern,silly_string)
print match.group()

现在,你能够看到单词“word”有两个实例,但是我们仅仅找出一个。找出所有实例共有两个方法。首先,我们看一下findall函数:

import re
silly_string = "the cat in the hat"
pattern = "the"
print re.findall(pattern,silly_string)

findall函数将会搜索整个字符串,并将每个匹配添加到列表中。一旦它结束在字符串中的搜索,它就会返回匹配列表。另一种查找多匹配的方法是使用finditer函数。

import re
silly_string = "the cat in the hat"
pattern = "the"
for match in re.finditer(pattern,silly_string):s = "Found '{group}' at {begin}:{end}".format(group = match.group(),begin=match.start(),end = match.end())print(s)

正如你所猜测,finditer方法返回匹配实例的迭代器而非findall函数得到的字符串。我们需要做的就是将结果格式化,然后再打印出来。

2.7 反斜杠

反斜杠在Python中正则表达式有些复杂。原因就是正则表达式使用反斜杠来表示特殊形式或者允许其成为可搜索的特殊字符而非直接调用,例如,我们想搜索美元符号:$。如果我们不使用反斜杠,我们仅仅是创建一个锚。原因就是Python将反斜杠字符作为字面字符使用。让我们看看类似于“python”字符串的搜索结果。

为了在正则表达式中进行搜索,你需要去除反斜杠,但是由于Python也使用反斜杠,反斜杠也需要被去除,于是你的搜索模式就是“\python”。幸运的事,Python通过在字符串开始处添加字母‘r’就可以支持原始字符串。所以我们可以以r“\python”格式使得更加可读。

如果你需要使用反斜杠进行搜索,请确认使用了原始字符串,否则将会遇到未知的结果。

2.8 总结

这篇博文大致总结了正则表达式可以做的任务。实际上,还有很多超出模块本身的任务。有一本关于正则表达式的书,这里主要告诉你基本的知识。当你正在使用正则表达式时,可能需要你查找更多的例子并阅读官方文档。当你需要它时,它确实是一个好用的工具。

3 Reference

Python 201

转载于:https://www.cnblogs.com/zhbzz2007/p/6813836.html

Python标准模块—Regular Expressions相关推荐

  1. Python标准模块--logging

    Python标准模块--logging 参考http://www.cnblogs.com/zhbzz2007/p/5943685.html 1 logging模块简介 logging模块是Python ...

  2. python线程池模块_python并发编程之进程池,线程池,协程(Python标准模块--concurrent.futures(并发未来))...

    需要注意一下 不能无限的开进程,不能无限的开线程 最常用的就是开进程池,开线程池.其中回调函数非常重要 回调函数其实可以作为一种编程思想,谁好了谁就去掉 只要你用并发,就会有锁的问题,但是你不能一直去 ...

  3. Python全栈学习笔记day 40.5+:线程池和线程池的Python标准模块--concurrent.futures

    Python标准模块--concurrent.futures 源码:https://docs.python.org/dev/library/concurrent.futures.html #1 介绍: ...

  4. Python标准模块logging

    开发Python, 一直以来都是使用自己编写的logging模块. 比较土...... 今天发现python的标准模块的这个功能做的挺好, 记录一下, 以后使用模块来进行logging. 对于这个模块 ...

  5. python标准模块string

    python的标准模块string 先看string模块提供什么东东给我们使用: __all__ = ["ascii_letters", "ascii_lowercase ...

  6. Python标准模块--asyncio

    1 模块简介 asyncio模块作为一个临时的库,在Python 3.4版本中加入.这意味着,asyncio模块可能做不到向后兼容甚至在后续的Python版本中被删除.根据Python官方文档,asy ...

  7. python标准模块--os

    目录 1.介绍2.常用函数 1.介绍 os模块包含普遍的操作系统功能.如果你希望你的程序能够与平台无关的话,这个模块是尤为重要的.即它允许一个程序在编写后不需要任何改动,也不会发生任何问题,就可以在L ...

  8. python标准模块os

    os模块为平台特定的模块(posix.nt和mac)提供了一个包装器.所有平台上函数的API都是相同的,所以使用os模块可以提供一定的可移植性.不过,并不是所有函数在每一个平台上都可用,许多进程管理函 ...

  9. Python标准模块--multiprocessing

    1 模块简介 multiprocessing模块在Python2.6中引入.最初的multiprocessing是由Jesse Noller和Richard Oudkerk在PEP 371中定义.就像 ...

最新文章

  1. 机器学习数据不平衡不均衡处理之SMOTE算法实现
  2. 力扣(LeetCode)刷题,简单+中等题(第35期)
  3. Oracle 11.2 安装Oracle 11.1的HR schoma
  4. vue 实现ps图片编辑_帮你解锁一个新技能,opencv完美媲美PS,图片PS,我们代码实现...
  5. Python reload() 函数
  6. asp.net 获取全部在线用户_Qamp;A | 在线考试问卷答疑
  7. php同步邮件,php – 使用同步驱动程序在Laravel 4中排队电子邮件
  8. 阶段1 语言基础+高级_1-3-Java语言高级_06-File类与IO流_04 IO字节流_2_一切皆为字节...
  9. 站群php自动地图,Discuz自动采集-DZ站群系统自动更新-Discuz站群管理系统
  10. php文件格式,php是什么文件格式
  11. 如何把NDI|HX2视频源通过高清解码器进行解码?
  12. 用Qt实现一个桌面弹幕程序(六)-- -- 桌面客户端实现②
  13. C语言试题八十六之兔子生兔子问题
  14. 算法导论第三章思考题
  15. 真正的高手,都在自讨苦吃——数显之家快讯之【SHIO世硕心语】
  16. Wifi网络共享----Connectify 使用
  17. 1加9pro刷个lineageOS Android11
  18. 计算机网络——知识点
  19. condition_variable的使用以及与锁的关系
  20. 将QLV视频格式转换为MP4格式

热门文章

  1. python有道翻译接口-Python通过调用有道翻译api实现翻译功能示例
  2. python读取excel日期内容读出来是数字-Python xlrd读取excel日期类型的2种方法
  3. python爬虫项目-33个Python爬虫项目实战(推荐)
  4. Tensorflow2.0报错:ProfilerNotRunningError: Cannot stop profiling. No profiler is running.
  5. windows10下编译dllib报错: ERROR: Failed building wheel for dlib
  6. Opengl-基本概念-可编程的渲染管线(僵硬啊)
  7. LeetCode Find K Pairs with Smallest Sums(大根堆、小根堆)
  8. LeetCode Simplify Path(栈操作)
  9. LeetCode Intersection of Two Arrays
  10. ArrayList、LinkedList和Vector