Python - 正则表达式(一)

正则表达式(regular expression)在编程中占有重要地位,它能够按照指定的方式匹配具有某种结构的字符串。本文将对此技术给予详述。

Python中的正则表达式

假设有一个字符串s,在程序中,需要检查'123'是否为这个字符串的一部分,这种需求可以用下面的代码实现。

>>> s = 'foo123bar'
>>> '123' in s
True

如果你不仅想知道'123'是否在字符串s中,还想知道它在字符串的什么位置,可以使用字符串的.find()或者.index()方法,返回'123'在s中的索引。

>>> s = 'foo123bar'
>>> s.find('123')
3
>>> s.index('123')
3

在上面的例子中,是按照字符一一对应的方式匹配的,这种方式会适用于很多地方,但是,有时候也会有更复杂的问题。比如,判断字符串中是否有像'123'这样有数字组成的字符串,例如'foo123bar'、'foo456bar'、'234baz'、和'qux678'`,再用上面的方法,就会太麻烦了,这就要正则表达式出场了。

正则表达式极简史

1951年,数学家斯Stephen Cole Kleene提出了正则表达式,20世纪60年代中期,计算机科学先驱Ken Thompson——Unix的原始设计师之一,他使用Kleene创造的符号在QED文本编辑器中实现了模式匹配。

自那时以来,正则表达式就出现在了许多编程语言、编辑器和其他工具中,作为确定字符串是否与指定模式匹配的方法,Python、Java 和 Perl等 都支持正则表达式,大多数Unix工具和许多文本编辑器都支持正则表达式。

re模块

Python中的正则表达式用re模块实现,它包括很多实用的方法,接下来,会介绍其中的大部分。

现在,先来研究re.search()。

re.search(, )

    Scans a string for a regex match.

re.search(, )按照参数所设置的正则表达式,扫描参数的字符串,这个过程可以称为“匹配”,如果有符合正则表达式结构的子字符串,即匹配存在,就会返回第一个所匹配的对象,否则返回None。

后面还会介绍,re.search()中的第三个参数

怎么使用re.search()

基本使用方法如下:

import re
re.search(...)
熟悉模块使用方法的,可能会知道,还能这样做:

from re import search
search(...)

示例

下面的示例,演示re.search()的基本应用:

>>> s = 'foo123bar'
>>> import re
>>> re.search('123', s)
<_sre.SRE_Match object; span=(3, 6), match='123'>

在上面示例中,就是123,是字符串s,最后返回了匹配结果,有此结果,我们至少知道字符串s中含有'123'。

如果写一个比较完整的程序,可以用条件语句判断一下:

>>> if re.search('123', s):
...     print('Found a match.')
... else:
...     print('No match.')
...
Found a match.

前面代码中返回结果<_sre.SRE_Match object; span=(3, 6), match='123'>,其中的span(3, 6)意思是字符串中匹配出现的位置,与切片的含义一样。

>>> s[3:6]
'123'

不过,上面的例子显然没有体现正则表达式的优势,只说明了它的基本操作流程。

正则表达式中的元字符

在正则表达式中,有一些特定字符,它们被称为元字符,每个元字符,代表了正则表达式中的某个特殊含义,能够满足正则匹配搜索引擎的查询之需。

例如,一组方括号([ ])表示了一个元字符类,即匹配字符类中的任何一个字符:

>>> s = 'foo123bar'
>>> re.search('[0-9][0-9][0-9]', s)
<_sre.SRE_Match object; span=(3, 6), match='123'>

[0-9]表示要匹配0到9的任何一个数字字符,[0-9][0-9][0-9]则表示匹配连续三个0到9之间的任何数字字符,在字符串s中,符合要求的就是123。

>>> re.search('[0-9][0-9][0-9]', 'foo456bar')
<_sre.SRE_Match object; span=(3, 6), match='456'>

>>> re.search('[0-9][0-9][0-9]', '234baz')
<_sre.SRE_Match object; span=(0, 3), match='234'>

>>> re.search('[0-9][0-9][0-9]', 'qux678')
<_sre.SRE_Match object; span=(3, 6), match='678'>

如果没有连续的三个数字字符,就不会匹配。

>>> print(re.search('[0-9][0-9][0-9]', '12foo34'))
None

另外一个元字符的例子是“句点”(.),它表示任何一种类型的字符(除了换行符):

>>> s = 'foo123bar'
>>> re.search('1.3', s)
<_sre.SRE_Match object; span=(3, 6), match='123'>

>>> s = 'foo13bar'
>>> print(re.search('1.3', s))
None

在第一个例子中,1和3是明显有匹配的,.匹配了2。但是,第二个示例则没有匹配。

re模块的元字符

下表中列出的,是re模块支持的元字符。


下面以示例说明部分元字符的应用。

字符类符号:[ ]

[ ]里面表示的字符类,即要匹配的一个字符集合。

>>> re.search('ba[artz]', 'foobarqux')
<_sre.SRE_Match object; span=(3, 6), match='bar'>
>>> re.search('ba[artz]', 'foobazqux')
<_sre.SRE_Match object; span=(3, 6), match='baz'>

[artz]表示4个独立的字符,在上面的示例中,正则表达式ba[artz]匹配了字符串中的bar和baz,当然,如果有可能,还可以匹配baa、bat。

字符集中,可以用-表示字符序列的范围,例如[a-z]表示匹配英文小写字母a到z中的任何一个字母。

>>> re.search('[a-z]', 'FOObar')
<_sre.SRE_Match object; span=(3, 4), match='b'>

[0-9]表示任何一个数字字符:

>>> re.search('[0-9][0-9]', 'foo123bar')
<_sre.SRE_Match object; span=(3, 5), match='12'>

在这个示例中,[0-9][0-9]表示匹配两个数字组成的字符串,对于字符串foo123bar,匹配了第一次出现的符合正则表达式的部分。

[0-9a-fA-F]表示16进制的任何一个字符。

>>> re.search('[0-9a-fA-f]', '--- a0 ---')
<_sre.SRE_Match object; span=(4, 5), match='a'>

这里匹配了第一个出现的16进制的字符a。

也可以在字符类中以^作为第一个字符,则表示要匹配该字符类的补集,即所有不是字符集中的字符。如下所示,[^0-9]表示非数字字符。

>>> re.search('[^0-9]', '12345foo')
<_sre.SRE_Match object; span=(5, 6), match='f'>

这里匹配的结果是第一个非数字的字母字符f。如果^不在首位,就没有了上面那种特殊含义了,仅仅是一个普通的^符号。

>>> re.search('[#:^]', 'foo^bar:baz#qux')
<_sre.SRE_Match object; span=(3, 4), match='^'>

前面已经说过,-表示了字符范围,但是,如果希望在正则表达式中匹配一个连字符-,怎么办?如果-在首位或者末尾,就表示连字符本身,如果在中间,可以只用转义符。

>>> re.search('[-abc]', '123-456')
<_sre.SRE_Match object; span=(3, 4), match='-'>
>>> re.search('[abc-]', '123-456')
<_sre.SRE_Match object; span=(3, 4), match='-'>
>>> re.search('[ab-c]', '123-456')
<_sre.SRE_Match object; span=(3, 4), match='-'>

同样,对于]符号,也可以用类似方法处理。

>>> re.search('[]]', 'foo[1]')
<_sre.SRE_Match object; span=(5, 6), match=']'>
>>> re.search('[ab]cd]', 'foo[1]')
<_sre.SRE_Match object; span=(5, 6), match=']'>

在[ ]所设定的字符集中,其他各种元字符都失掉了作为元字符的含义。

>>> re.search('[)*+|]', '123*456')
<_sre.SRE_Match object; span=(3, 4), match='*'>
>>> re.search('[)*+|]', '123+456')
<_sre.SRE_Match object; span=(3, 4), match='+'>

这些元字符都编程了普通的字符。

(未完,待续)

展开阅读全文

页面更新:2024-04-02

标签:示例   字符串   字母   符号   字符   模块   含义   例子   数字   方法

1 2 3 4 5

上滑加载更多 ↓
推荐阅读:
友情链接:
更多:

本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828  

© CopyRight 2008-2024 All Rights Reserved. Powered By bs178.com 闽ICP备11008920号-3
闽公网安备35020302034844号

Top