您的位置:首页 > 编程语言 > Python开发

Python 正则表达式——快速入门

2017-04-27 00:12 483 查看

简介

正则表达式,又称正规表示式、规则表达式等(英语:Regular Expression,常简写为regex、regexp或RE),是计算机科学的一个概念。正则表达式使用单个字符串来描述、匹配一系列匹配某个句法规则的字符串。在很多文本编辑器里,正则表达式通常被用来检索、替换那些匹配某个模式的文本。维基百科

正则表达式是一些由字符串和特殊符号组成的字符串,描述了模式的重复或者表述多个字符,能按照某种模式匹配一系列有相似特征的字符串。python通过标准库中的re模块来支持正则表达式,本文作为新手快速入门笔记,将简洁介绍正则表达式的语法和re库的基本使用(文本所使用的版本为Pyhton2.7)。

正则表达式语法

1. 常用操作符

正则表达式语法由字符和特殊符号构成,即所谓的元字符,正是它给予正则表达式强大的功能和灵活性。下面列出常见的符号和字符。

表示法说明实例
符号
literal匹配文本字符串的字面值literalfoo
re1|re2匹配正则表达式re1或re2foo|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. 正则表达式语法实例

正则表达式模式匹配的字符串
foofoo
at|homeat、home
PYTHON+PYTHON、PYTHONN、PYTHONN…
PYONPYHON、PYHON
PY[^TH]?ONPYON、PYaON、PYbON…
PY{,3}NPN、PYN、PYYN、PYYYN
^From任何以From作为起始的字符串
b[aeiu]tbat、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模块官方帮助文档
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息