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

来源:互联网 发布:天播网络机顶盒刷系统 编辑:程序博客网 时间:2024/04/29 06:41

简介

正则表达式,又称正规表示式、规则表达式等(英语: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[TH]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库主要功能函数

re库主要功能函数

  1. 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'
  2. 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语句

  3. 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']>>> 
  4. 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()... 100081100084>>> 
  5. 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']>>> 
  6. 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.pos0>>> m.endpos20>>> m.group()'100081'>>> m.group(0) #等价于m.group()'100081'>>> m.group(1) #没有子组,返回编号为1的子组报错,抛出IndexErrorTraceback (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模块官方帮助文档


0 0
原创粉丝点击