Python 正则表达式——快速入门
2017-04-27 00:12
483 查看
简介
正则表达式,又称正规表示式、规则表达式等(英语:Regular Expression,常简写为regex、regexp或RE),是计算机科学的一个概念。正则表达式使用单个字符串来描述、匹配一系列匹配某个句法规则的字符串。在很多文本编辑器里,正则表达式通常被用来检索、替换那些匹配某个模式的文本。维基百科正则表达式是一些由字符串和特殊符号组成的字符串,描述了模式的重复或者表述多个字符,能按照某种模式匹配一系列有相似特征的字符串。python通过标准库中的re模块来支持正则表达式,本文作为新手快速入门笔记,将简洁介绍正则表达式的语法和re库的基本使用(文本所使用的版本为Pyhton2.7)。
正则表达式语法
1. 常用操作符
正则表达式语法由字符和特殊符号构成,即所谓的元字符,正是它给予正则表达式强大的功能和灵活性。下面列出常见的符号和字符。表示法 | 说明 | 实例 |
---|---|---|
符号 | ||
literal | 匹配文本字符串的字面值literal | foo |
re1|re2 | 匹配正则表达式re1或re2 | foo|bar 表示foo或bar |
. | 匹配任何单个字符(除了\n之外) | |
[…] | 匹配来自字符集的任意单一字符 | [abc]表示a或b或c |
^ | 匹配字符串起始部分 | ^abc表示abc且在一个字符串的开头 |
$ | 匹配字符串结尾部分 | abc$表示abc且在一个字符串的结尾 |
* | 匹配0次或多次前一个正则表达式 | abc*表示ab、abc、abcc、abccc等 |
+ | 匹配1次或多次前一个正则表达式 | abc+表示abc、abcc、abccc等 |
? | 匹配0次或1次前一个正则表达式 | abc?表示ab、abc |
[^…] | 不匹配次字符集中出现的任何一字符 | [^abc]表示非a或b或c的单个字符 |
{N} | 匹配N次前面出现的正则表达式 | ab{2}c表示abbc |
{M,N} | 匹配M~N次前面出现的正则表达式 | ab{1,2}c表示abc、abbc |
(…) | 分组标记,匹配封闭的正则表达式,然后另存为子组 | (abc)表示abc |
特殊字符 | ||
\d | 匹配任何十进制数字,与[0-9]一致(\D与\d相反) | |
\w | 匹配任何字母数字字符,与[A-Za-z0-9]相同(\W与之相反) | |
\s | 匹配任何空格字符,与[\n\t\r\v\f]相同(\S与之相反) | |
\b | 匹配任何单词边界(\B与之相反) | |
\N | 匹配已保存的子组N(参见符号(…)) | |
\c | 逐字匹配任何特殊字符c(即,仅按字面意义匹配) | \.,\*,\\(匹配.,*,\) |
\A(\Z) | 匹配字符串的起始(结束)位置(参见^和$) |
2. 正则表达式语法实例
正则表达式模式 | 匹配的字符串 | |
---|---|---|
foo | foo | |
at|home | at、home | |
PYTHON+ | PYTHON、PYTHONN、PYTHONN… | |
PY | ON | PYHON、PYHON |
PY[^TH]?ON | PYON、PYaON、PYbON… | |
PY{,3}N | PN、PYN、PYYN、PYYYN | |
^From | 任何以From作为起始的字符串 | |
b[aeiu]t | bat、bet、bit、but | |
[^\t\n] | 不匹配制表符或者\n | |
[“-a] | 在一个ASCII系统中,所有字符都位于”和a之间,即34~97之间 |
3. 经典正则表达式实例
正则表达式模式 | 匹配的字符串 |
---|---|
^[A-Za-z]+$ | 由26个字母组成的字符串 |
^[A-Za-z0-9]+$ | 由26个字母和数字组成的字符串 |
^-?\d+$ | 整数形式的字符串 |
^[0-9]*[1-9][0-9]*$ | 正整数形式的字符串 |
[1-9]\d{5} | 中国境内邮政编码,6位 |
\d{3}-\d{8}|\d{4}-\d{7} | 国内电话号码,010-68913536 |
\d{3}-\d{3}-\d{4} | 美国电话号码的格式,800-555-1212 |
[\u4e00-\u9fa5] | 匹配中文字符 |
[0-9]{15,16} | 匹配15或16个数字,例如信用卡号码 |
\w+@\w+.com | 以XXX@YYY.com格式表示的简单电子邮件地址 |
re库的基本使用
re库是Python的标准库,主要用于字符串匹配。re模块支持更强大且更通用的Perl风格(Perl风格)的正则表达式,该模块允许多个线程共享同一个已编译的正则表达式对象,也支持命名子组。1. re库主要功能函数
search()函数
函数定义:re.search(pattern, string, flags=0)
在一个字符串中搜索匹配正则表达式的第一个位置,成功返回match对象,失败返回None
pattern:正则表达式的字符串或原生字符串表示
string: 带匹配字符串
flags: 正则表达式使用时的控制标记
示例:
>>> import re >>> m = re.search('foo', 'seafood') >>> if m is not None: m.group() ... 'foo'
match()函数
函数定义:re.match(pattern, string, flags=0)
在一个字符串中搜索匹配正则表达式的第一个位置,成功返回match对象,失败返回None
pattern:正则表达式的字符串或原生字符串表示
string: 带匹配字符串
flags: 正则表达式使用时的控制标记
示例:
>>> import re >>> match = re.match(r'[1-9]\d{5}','BIT 100081') >>> if match: ... match.group() ... >>> match.group() Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: 'NoneType' object has no attribute 'group' >>> >>> match = re.match(r'[1-9]\d{5}','100081 BIT') >>> if match: ... match.group() ... '100081'
注意:match()函数是从字符串的起始部分对模式进行匹配,当匹配失败是会抛出AttributeError异常,不能省略if语句
findall()函数
函数定义:re.findall(pattern, string, flags=0)
查找字符串中所有(非重复)出现的正则表达式模式,以列表类型返回全部能匹配的子串
pattern:正则表达式的字符串或原生字符串表示
string: 带匹配字符串
flags: 正则表达式使用时的控制标记
示例:
>>> import re >>> ls = re.findall(r'[1-9]\d{5}','BIT100081 TSU100084') >>> ls ['100081', '100084'] >>>
finditer()函数
函数定义:re.finditer(pattern, string, flags=0)
查找字符串,返回的不是列表,而是一个迭代器,每个迭代元素是match对象
pattern:正则表达式的字符串或原生字符串表示
string: 带匹配字符串
flags: 正则表达式使用时的控制标记
示例:
>>> import re >>> for m in re.finditer(r'[1-9]\d{5}','BIT100081 TSU100084'): ... if m: ... print m.group() ... 100081 100084 >>>
split()函数
函数定义:re.split(pattern, string, maxsplit=0, flags=0)
将一个字符串按照正则表达式匹配结果进行分割,返回列表类型,分割最多操作maxsplit次
pattern:正则表达式的字符串或原生字符串表示
string: 带匹配字符串
maxsplit: 最大分割数,剩余部分作为最后一个元素输出
flags: 正则表达式使用时的控制标记
示例:
>>> import re >>> re.split(r'[1-9]\d{5}','BIT100081 TSU100084') ['BIT', ' TSU', ''] >>> re.split(r'[1-9]\d{5}','BIT100081 TSU100084',maxsplit=1) ['BIT', ' TSU100084'] >>>
sub()函数
函数定义:re.sub(pattern, repl, string, count=0, flags=0)
在一个字符串中替换所有匹配正则表达式的子串,返回替换后的字符串
pattern:正则表达式的字符串或原生字符串表示
repl : 替换匹配字符串的字符串
string : 带匹配字符串
count : 匹配的最大替换次数
flags: 正则表达式使用时的控制标记
示例:
>>> import re >>> re.sub(r'[1-9]\d{5}',':zipcode','BIT100081 TSU100084') 'BIT:zipcode TSU:zipcode' >>>
2. 常用的控制标记
对于一些特别的正则表达式编译,可选的标记可能以参数的形式给出。它们可以通过按位或者操作符(|)合并,也可以直接嵌入到正则表达式本身(?F),其中F是一个或多个i(用于re.I/IGNORECASE)、m(用于re.M/MULTILINE)等,如(?im)。常用标记 | 说明 |
---|---|
re.I re.IGNORECASE | 不区分大小写的匹配,[A-Z]能够匹配小写字符 |
re.M re.MULTILINE | ^和$分别匹配目标字符串中行的起始和结尾,而不是严格匹配整个字符串本身的起始和结尾 |
re.S re.DOTALL | “.”(点号)默认匹配除了\n(换行符)以外的所有单个字符,该标记表示点号能够匹配全部字符 |
3. re库的等价用法
函数式用法:一次性操作>>> rst = re.search(r'[1-9]\d{5}','BIT 100081')
等价于
面向对象用法,编译后可多次操作
>>> pat = re.compile(r'[1-9]\d{5}') >>> rst = pat.search('BIT 100081')
Python解释器在执行字符串形式的代码前都必须把字符串编译成代码对象,使用预编译的代码对象比直接使用字符串要快。同样的概念也适用于正则表达式——在模式匹配之前,正则表达式模式必须编译成正则表达式对象。由于正则表达式在执行过程中将进行多次比较操作,因此强烈建议使用预编译来提升执行性能,re.compile( )能够提供此功能。
其实模块函数会对已编译的对象进行缓存,不是所有使用形同正则表达式模式的search( )和match( )都需要编译。在不同的Python版本中,缓存中已编译过的正则表达式对象的数目可能不同,而且没有文档记录。purge( )函数能够用于清除这些缓存。几乎所有的re模块函数都可以作为regex对象的方法。尽管推荐预编译,但它并不是必需的。
函数定义:regex = re.compile(pattern, flags=0)
将正则表达式的字符串形式编译成正则表达式对象
- pattern:正则表达式的字符串或原生字符串表示
- flags: 正则表达式使用时的控制标记
示例: ``` >>> import re >>> regex = re.compile(r'[1-9]\d{5}') >>> ```
4. re库的match对象
match对象是一次匹配的结果,包含匹配的很多信息。>>> match = re.search(r'[1-9]\d{5}','BIT 100081') >>> if match: ... print match.group() ... 100081 >>> type(match) <type '_sre.SRE_Match'>
match对象的方法
方法 | 说明 |
---|---|
.string | 带匹配的文本 |
.re | 匹配时使用的pattern对象(正则表达式) |
.pos | 正则表达式搜索文本的开始位置 |
.endpos | 正则表达式搜索文本的结束位置 |
.group(num=0) | 返回整个匹配对象,或者返回编号为num的特定子组,默认num=0 |
.groups( ) | 返回一个包含所有匹配子组的元组,若匹配失败,则返回一个空元组 |
.start( ) | 匹配字符串在原始字符串的开始位置 |
.end( ) | 匹配字符串在原始字符串的结束位置 |
.span( ) | 返回元组(.start(), .end()) |
m = re.search(r'[1-9]\d{5}','BIT 100081 TSU100084') >>> m.string 'BIT 100081 TSU100084' >>> m.re <_sre.SRE_Pattern object at 0x7f244e345ab0> #regex对象在内存中的地址 >>> m.pos 0 >>> m.endpos 20 >>> m.group() '100081' >>> m.group(0) #等价于m.group() '100081' >>> m.group(1) #没有子组,返回编号为1的子组报错,抛出IndexError Traceback (most recent call last): File "<stdin>", line 1, in <module> IndexError: no such group >>> m.groups() #没有子组,返回空元组 () >>> m.start() 4 >>> m.end() 10 >>> m.span() (4, 10)
5. re库的贪婪匹配和最小匹配
实例:>>> match = re.search(r'PY.*N','PYANBNCNDN') >>> match.group() 'PYANBNCNDN'
re库默认采用贪婪匹配,即输出匹配最长的子串。
如何输出最短的子串呢?
最小匹配
>>> match_min = re.search(r'PY.*?N','PYANBNCNDN') >>> match_min.group() 'PYAN'
最小匹配操作符
操作符 | 说明 |
---|---|
*? | 前一个字符0次或多次扩展,最小匹配 |
+? | 前一个字符1次或多次扩展,最小匹配 |
?? | 前一个字符0次或1次扩展,最小匹配 |
{m,n}? | 扩展前一个字符m至n次(含n),最小匹配 |
总结
在介绍正则表达式常用语法的基础上,学习了Python正则表达式re模块的常用方法,满足一般常用的需求,后面将会进一步总结正则表达式的扩展表示法和其实际应用。正则表达式为高级的文本模式匹配、抽取、与/或文本形式的搜索和替换功能提供了基础,与爬虫结合将展示其巨大的威力。Python2.7模块官方帮助文档
相关文章推荐
- Python快速入门(5)正则表达式
- 正则表达式快速入门(python示例)
- Python学习笔记(四):面向对象、正则表达式(快速入门篇)
- 正则表达式基础(python快速入门精华切记04)
- 正则表达式快速入门
- python的小实验代码的备份,主要偏向于爬虫方向,难点是正则表达式和编码转换[入门]
- 正则表达式快速入门
- python3爬虫之入门和正则表达式
- 正则表达式快速入门(二)
- 第01阶段-基础入门-02-Python 爬虫基础-21节=====12.认识正则表达式
- C#正则表达式快速入门
- python3爬虫初级入门和正则表达式
- Python爬虫—1入门_4_正则表达式
- JavaScript中的正则表达式快速入门
- 正则表达式快速入门
- 正则表达式快速入门
- Python网络爬虫与信息提取-Day12-Re(正则表达式)库入门
- 零基础学python-18.6 lambda表达式快速入门
- 正则表达式快速入门
- 正则表达式快速入门